重新加载表视图数据并取消选择单元格

我有一个表视图,我想在从详细视图返回时,或者在用户创建项目时从新添加的单元格中取消选择先前选择的单元格。

但是,由于有时会添加新项,因此通过在viewWillAppear:调用reloadData来刷新表viewWillAppear: 。 这意味着即使我有self.clearsSelectionOnViewWillAppear = NO ,也不会在视图出现时选择任何单元格。

通过在表视图出现选择和取消选择单元格(在viewDidAppear:中,取消选择动画的时间明显不同于用户(尝试自己,它更慢,并且感觉不是那么光滑)。

即使在刷新表格视图后,我应该如何保留选择? (请记住,根据具体情况,我要取消选择之前选择的单元格或新创建的单元格。)或者我应该以某种方式重新加载表格中的数据?

您可以从- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath方法保存NSIndexPath ,并在视图重新加载时取消选择该行。

另一种方法是将NSIndexPath和当前的UITableViewController传递给你正在创建的UIViewController ,当弹出UIViewController时,你取消选择特定的行。

创建新项目时,将一个项目添加到indexPath的行元素以取消选择右侧行。

您还可以仅重新加载已更改的行:

 [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 

更高级的解决方案

  • 它适用于[self.tableView reloadData]
  • 重新加载后缺少选定的行时,它不会崩溃。

示例MyViewController.m部分代码:

 @interface MyViewController () { MyViewModel* _viewModel; NSString* _selectedItemUniqueId; } @property (nonatomic, weak) IBOutlet UITableView* tableView; @end @implementation MyViewController #pragma mark - UIViewController methods - (void)viewDidLoad { [super viewDidLoad]; _selectedItemUniqueId = nil; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.tableView reloadData]; } #pragma mark - UITableViewDelegate - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath { // Get data for selected row. Item* item = _viewModel.data.sections[indexPath.section].items[indexPath.row]; // Remember selection that we could restore it when viewWillAppear calls [self.tableView reloadData]. _selectedItemUniqueId = item.uniqueId; // Go to details view. } - (void)tableView:(UITableView*)tableView willDisplayCell:(nonnull UITableViewCell *)cell forRowAtIndexPath:(nonnull NSIndexPath *)indexPath { // Get data for row. Item* item = _viewModel.data.sections[indexPath.section].items[indexPath.row]; // Bring back selection which is destroyed by [self.tableView reloadData] in viewWillAppear. BOOL selected = _selectedItemUniqueId && [item.uniqueId isEqualToString:_selectedItemUniqueId]; if (selected) { _selectedItemUniqueId = nil; [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; } } @end