【问题标题】:UITableViewCell won't be swiped to trigger action more than once since iOS 11自 iOS 11 以来,UITableViewCell 不会被多次滑动触发动作
【发布时间】:2018-09-02 17:25:33
【问题描述】:

自从 Apple 发布 iOS 11 和 trailingSwipeActions 功能后,我的应用程序出现了回归问题。

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

它可以完美运行,但不适用于 iOS 11。滑动操作只能执行一次,然后它就不再适用于所有行,单元格只是不滑动。我在调试控制台中有以下消息。

*** NSForwarding:警告:方法签名和编译器在 'prepareWithSwipeDirection:configuration:' 的 struct-return-edness 上存在分歧。 签名认为它不返回结构,编译器认为它 可以。

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

我已尝试实现 iOS 11 附带的有关此功能的所有新功能,但没有任何解决我的问题。

还试图弄清楚是否某些 GestureRecognizer 随机“吃掉”了手势但没有找到任何相关的东西,这也很难调试。

这是我尝试不同更改后的相关代码:

- (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;
}

感谢您的帮助。

【问题讨论】:

  • 为什么你的方法被定义为返回 id 而不是 UISwipeActionsConfiguration?
  • 感谢您的帮助,我已修复并再次尝试,结果相同。
  • 在这里找到一条关于该问题的资料(中文):fanwt.com/2017/12/08/…
  • 同样的事情对我有用..

标签: ios objective-c uitableview cocoa-touch ios11


【解决方案1】:

这是由于我的代码中的一段代码引起的混乱:

@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; 解决了这个问题。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    相关资源
    最近更新 更多