自 iOS 11 起,不会多次滑动 UITableViewCell 触发操作

UITableViewCell won't be swiped to trigger action more than once since iOS 11

自从 Apple 发布 iOS 11 和 trailingSwipeActions 功能后,我的应用程序出现了退化。

我的 TableView 显示消息并允许用户通过向左滑动显示删除按钮来删除消息。

它完美运行,但在 iOS 上运行不佳 11. 滑动操作只能进行一次,然后它对所有行都不再起作用,单元格不会滑动。我在调试控制台中收到以下消息。

*** NSForwarding: warning: method signature and compiler disagree on struct-return-edness of 'prepareWithSwipeDirection:configuration:'. Signature thinks it does not return a struct, and compiler thinks it does.

每次都会调用trailingSwipeActionsConfigurationForRowAtIndexPath方法,但是单元格就是不滑动

我已经尝试实现 iOS 11 中关于此功能的所有新功能,但没有解决我的问题。

还试图弄清楚是否有一些 GestureRecognizer 是随机 "eating" 手势但没有找到任何相关的东西,也很难调试。

下面是我尝试过不同修改后的相关代码:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

- (BOOL) tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    return NO;
}

- (BOOL) tableView:(UITableView *)tableView canFocusRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
    return NO;
}

- (BOOL) tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
    return NO;
}


- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (@available(iOS 11.0, *)) {
        UIContextualAction * delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"Delete" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
            [self deleteMessageAtIndexPath:indexPath];
        }];
        UISwipeActionsConfiguration *configuration = [UISwipeActionsConfiguration configurationWithActions:@[delete]];
        configuration.performsFirstActionWithFullSwipe = false;
        return configuration;
    }
    return nil;
}

- (NSArray<UITableViewRowAction *> *) tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
    UITableViewRowAction * delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"Delete" handler:^(UITableViewRowAction * action, NSIndexPath * indexPath){
        [self deleteMessageAtIndexPath:indexPath];
    }];
    return @[delete];
}

- (void) deleteMessageAtIndexPath:(NSIndexPath *)indexPath {
    NSString *threadID = [[self.messageArray objectAtIndex:indexPath.row] objectForKey:@"threadID"];
    [self.tableView beginUpdates];
    [self.messageArray removeObjectAtIndex:indexPath.row];
    [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView endUpdates];

    //[self.tableView reloadData];

    @weakify(self);
    [UIUtil showLoadingHudWithText: @"Deleting..."];
    [[AsyncUtil sharedInstance] dispatch_background_network:^{
        DBManager *db = [[DBManager alloc] init];
        [db deletetableData:[NSString stringWithFormat:@"singleChat WHERE threadID = '%@' ",threadID] ];
        [[MemChatThreadMessages sharedInstance] removeThread:threadID];
        NSDictionary * result = [Network deleteChatThread:threadID forEmail:[WEUtil getEmail]];
        [[AsyncUtil sharedInstance] dispatch_main:^{
            [UIUtil hideLoadingHuds];
            @strongify(self);
            if(self == nil) return ;

            if([result[@"result"] isEqualToString:@"success"]){

            }else{
                //[self.tableView reloadData];
                [UIUtil showErrorMessage:@"Cannot delete this thread"];
            }
        }];
    }];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}

感谢您的帮助。

这是由于我的代码中的一个片段引起的 swizzling 造成的:

@implementation NSMutableDictionary (NilSafe)


- (void)gl_setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key {
    if (!key) {
        return;
    }
    if (!obj) {
        obj = [NSNull null];
    }
    [self gl_setObject:obj forKeyedSubscript:key];
}

@end

这部分是导致错误的地方:

    if (!obj) {
        obj = [NSNull null];
    }

obj = [NSNull null]; 更改为 return; 解决了该问题。

原博客post关于问题的解决方法是here(中文)。