模型改变和行动画是否必须直接从 commitEditingStyle
开始?还是可以在以后的运行循环迭代中完成?
我问是因为它似乎可以在 iOS 10 上运行,但在 iOS 11 上它至少会破坏删除动画。它只是 iOS 11 中的一个错误,还是一般来说是个坏主意?
有没有更好的方法来触发异步删除操作并在完成时为 TableView 更改设置动画?
第一张图片显示了它在 iOS 11 上是如何中断的(删除按钮与下一个单元格重叠)。第二张图片显示了它在 iOS 10 上的外观。
这是有趣的片段:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
dispatch_async(dispatch_get_main_queue(), ^{
[_model removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
});
}
}
如果我删除
dispatch_async(...
,它在 iOS 10 和 11 上按预期工作。第一张图片显示 iOS 11,第二张显示 iOS 10。这是用于测试它的 TableView Controller 的完整代码:
#import "TableViewController.h"
@implementation TableViewController {
NSMutableArray<NSString *>* _model;
}
- (void)viewDidLoad {
[super viewDidLoad];
_model = [[NSMutableArray alloc] init];
[self.tableView registerClass:UITableViewCell.class forCellReuseIdentifier:@"cell"];
for (NSInteger i = 0; i < 200; i++) {
[_model addObject:[NSString stringWithFormat:@"Test Row %ld Test Test Test Test Test", (long)i]];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _model.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.textLabel.text = _model[indexPath.row];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
dispatch_async(dispatch_get_main_queue(), ^{
[_model removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
});
}
}
@end
更新:
将此方法添加到 table view controller 修复了 iOS 11 并允许延迟模型更改和行动画。 (感谢 ChrisHaze)
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(11_0) {
UIContextualAction* deleteAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"Delete" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
dispatch_async(dispatch_get_main_queue(), ^{
[_model removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
completionHandler(YES);
});
}];
UISwipeActionsConfiguration* config = [UISwipeActionsConfiguration configurationWithActions:@[deleteAction]];
return config;
}
最佳答案
iOS 11 中的 UITableview 似乎发生了变化。
Apple 的 Build 发行说明:
“删除滑动操作的行为已更改。实现commitEditingStyle:删除滑动行时,删除数据源中的行并在表格 View 上调用deleteRowsAtIndexPaths:以显示滑动删除动画。”
经过进一步研究,我发现您必须调用beginUpdates
在调用 deleteRowAtIndexPath:
之前方法,以及 endUpdates
后的方法。
根据苹果的 documentation ,不调用这些 tableView 方法将导致潜在的数据模型问题并影响删除动画。
话虽如此,有一个 answer其中包括解决非常相似问题的 Apple 开发论坛上的问题所需的代码。
回答您的实际问题:
---------------------------------------- additional details ----------------------------
在查看了您评论中的详细信息后,我提供了一个链接(上图),它是 Apple 提供的最新 Table View Programming Guide。它将带您或遇到此问题的任何其他人进入指南部分,其中包含您添加到问题中的详细信息。
还有一个好用的注意 其中包括如何制作
deleteRowAtIndexPath
从commitEditingStyle
内调用电话如果必须的方法。
关于ios - 延迟 commitEditingStyle 中的模型和 TableView 更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47147342/