[英]Odd animations with swipe to delete action in UITableView
我的UITableView遇到問題。 刪除滑動手勢的動畫無法正常工作。 關鍵是,在新的模板項目“ MasterDetail”中,它運行良好。 但不在我目前從事的項目中。
動畫制作之前,我還有另一個問題,這是第一次完成動畫后無法正常工作。 我通過替換代碼中的代碼來修復它。
/// New code
- (void)gl_setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key {
if (!key || !obj) {
return;
}
[self gl_setObject:obj forKeyedSubscript:key];
}
/// Old code
- (void)gl_setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key {
if (!key) {
return;
}
if (!obj) {
obj = [NSNull null];
}
[self gl_setObject:obj forKeyedSubscript:key];
}
這是當前TableView的代碼,該代碼正在Xcode基礎項目中工作,而在我的代碼中則無效。
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TempViewController: UIViewController
@end
NS_ASSUME_NONNULL_END
#import "TempViewController.h"
#import "TempTableViewCell.h"
@interface TempViewController () <UITableViewDelegate, UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property NSMutableArray *objects;
@end
@implementation TempViewController
- (void)viewDidLoad {
[super viewDidLoad];
// TableView
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.rowHeight = 80;
[self.tableView registerNib:[UINib nibWithNibName:@"TempTableViewCell" bundle:nil] forCellReuseIdentifier:@"TempTableViewCell"];
// Add button to add element when deleting too much
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
// Add some data to make the bug work
for (int i = 0; i < 100; i++) {
[self insertNewObject:0];
}
}
- (void)insertNewObject:(id)sender {
if (!self.objects) {
self.objects = [[NSMutableArray alloc] init];
}
[self.objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TempTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TempTableViewCell" forIndexPath:indexPath];
NSDate *object = self.objects[indexPath.row];
cell.tempLabel.text = [object description];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
@end
所以,我想知道伙計們,您對哪里看有什么線索嗎? 還是以前已經經歷過這個問題?
感謝您日后的幫助!! 建設愉快!
好,
我朝着更深層次的方向發展。 我完全刪除了此代碼。 我們使用它來避免在字典中插入nil值。 沒有它,錯誤消失了。 我不確定為什么,但是如果有一天我找到了答案,我將更新這篇文章。 希望可以為某些人節省時間!
#import "NSDictionary+NilSafe.h"
#import <objc/runtime.h>
@implementation NSObject (Swizzling)
+ (BOOL)gl_swizzleMethod:(SEL)origSel withMethod:(SEL)altSel {
Method origMethod = class_getInstanceMethod(self, origSel);
Method altMethod = class_getInstanceMethod(self, altSel);
if (!origMethod || !altMethod) {
return NO;
}
class_addMethod(self,
origSel,
class_getMethodImplementation(self, origSel),
method_getTypeEncoding(origMethod));
class_addMethod(self,
altSel,
class_getMethodImplementation(self, altSel),
method_getTypeEncoding(altMethod));
method_exchangeImplementations(class_getInstanceMethod(self, origSel),
class_getInstanceMethod(self, altSel));
return YES;
}
+ (BOOL)gl_swizzleClassMethod:(SEL)origSel withMethod:(SEL)altSel {
return [object_getClass((id)self) gl_swizzleMethod:origSel withMethod:altSel];
}
@end
@implementation NSDictionary (NilSafe)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self gl_swizzleMethod:@selector(initWithObjects:forKeys:count:) withMethod:@selector(gl_initWithObjects:forKeys:count:)];
[self gl_swizzleClassMethod:@selector(dictionaryWithObjects:forKeys:count:) withMethod:@selector(gl_dictionaryWithObjects:forKeys:count:)];
});
}
+ (instancetype)gl_dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt {
id safeObjects[cnt];
id safeKeys[cnt];
NSUInteger j = 0;
for (NSUInteger i = 0; i < cnt; i++) {
id key = keys[i];
id obj = objects[i];
if (!key) {
continue;
}
if (!obj) {
obj = [NSNull null];
}
safeKeys[j] = key;
safeObjects[j] = obj;
j++;
}
return [self gl_dictionaryWithObjects:safeObjects forKeys:safeKeys count:j];
}
- (instancetype)gl_initWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt {
id safeObjects[cnt];
id safeKeys[cnt];
NSUInteger j = 0;
for (NSUInteger i = 0; i < cnt; i++) {
id key = keys[i];
id obj = objects[i];
if (!key) {
continue;
}
if (!obj) {
obj = [NSNull null];
}
safeKeys[j] = key;
safeObjects[j] = obj;
j++;
}
return [self gl_initWithObjects:safeObjects forKeys:safeKeys count:j];
}
@end
@implementation NSMutableDictionary (NilSafe)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = NSClassFromString(@"__NSDictionaryM");
[class gl_swizzleMethod:@selector(setObject:forKey:) withMethod:@selector(gl_setObject:forKey:)];
[class gl_swizzleMethod:@selector(setObject:forKeyedSubscript:) withMethod:@selector(gl_setObject:forKeyedSubscript:)];
});
}
- (void)gl_setObject:(id)anObject forKey:(id<NSCopying>)aKey {
if (!aKey) {
return;
}
if (!anObject) {
anObject = [NSNull null];
}
[self gl_setObject:anObject forKey:aKey];
}
- (void)gl_setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key {
if (!key) {
return;
}
if (!obj) {
obj = [NSNull null];
}
[self gl_setObject:obj forKeyedSubscript:key];
}
@end
@implementation NSNull (NilSafe)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self gl_swizzleMethod:@selector(methodSignatureForSelector:) withMethod:@selector(gl_methodSignatureForSelector:)];
[self gl_swizzleMethod:@selector(forwardInvocation:) withMethod:@selector(gl_forwardInvocation:)];
});
}
- (NSMethodSignature *)gl_methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *sig = [self gl_methodSignatureForSelector:aSelector];
if (sig) {
return sig;
}
return [NSMethodSignature signatureWithObjCTypes:@encode(void)];
}
- (void)gl_forwardInvocation:(NSInvocation *)anInvocation {
NSUInteger returnLength = [[anInvocation methodSignature] methodReturnLength];
if (!returnLength) {
// nothing to do
return;
}
// set return value to all zero bits
char buffer[returnLength];
memset(buffer, 0, returnLength);
[anInvocation setReturnValue:buffer];
}
@end
編輯1:好吧,最后,問題是對obj的nil檢查
if (!key || !obj) {
return;
}
/// Replaced by
if (!key) {
return;
}
我保留了其余代碼,如果在NSDictionary中插入試圖插入nil值,則會產生崩潰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.