iOS 11后UITableView侧滑删除异常:每删一行多显示一行
嘿,我帮你排查过不少iOS 11之后UITableView删除行的奇怪问题,你遇到的这种「每侧滑删除一次就多显示一行」的情况,大概率是数据源和TableView操作不同步导致的——毕竟iOS 11对UITableView的编辑逻辑做了不少底层调整,咱们一步步来解决:
可能的问题原因&解决方案
1. 数据源更新和TableView操作顺序搞反了
这是最常见的坑!很多开发者会先调用deleteRowsAtIndexPaths:,再去修改数据源数组,这会直接导致TableView的UI和真实数据源不匹配,iOS 11之后这个问题会被放大。
正确顺序必须是:先改数据源,再通知TableView更新
示例代码:
// 第一步:先从你的数据源数组(比如self.chatMessages)里移除对应数据 [self.chatMessages removeObjectAtIndex:indexPath.row]; // 第二步:再告诉TableView删除对应行 [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
2. 别在editActionsForRowAtIndexPath里直接改数据源
你提供的代码里用到了editActionsForRowAtIndexPath,这个方法的作用只是创建删除按钮,绝对不能在这里直接修改数据源或者调用TableView的删除方法!
正确的做法是在删除按钮的handler里处理逻辑:
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { NSMutableArray *rowActions = [NSMutableArray array]; UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { // 在这里处理删除逻辑:先改数据源,再更UI [self.chatMessages removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; // 记得手动结束编辑状态,避免UI残留 [tableView setEditing:NO animated:YES]; }]; [rowActions addObject:deleteAction]; return rowActions; }
3. 检查numberOfRowsInSection的返回值
确保这个数据源方法是直接返回你的数据源数组长度,不要写固定值或者有其他错误逻辑:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // 必须返回真实数据源的长度 return self.chatMessages.count; }
如果这里返回的数值和实际数据源不匹配,删除后TableView计算行数就会出错,自然会多出一行。
4. 排查iOS 11的自动高度问题
iOS 11之后TableView默认开启了estimatedRowHeight,如果你的行高度计算有bug(比如返回0或者错误值),删除后可能会把空白区域当成有效行显示。
如果你的行高度是固定的,可以直接强制设置:
// 在viewDidLoad里设置 self.tableView.rowHeight = 70.0; self.tableView.estimatedRowHeight = 70.0;
如果是动态高度,一定要确保tableView:heightForRowAtIndexPath:能返回正确的高度值。
内容的提问来源于stack exchange,提问作者Maxime B
相关产品推荐
相关产品推荐

