【问题标题】:Reload Table View Data and Deselect Cell重新加载表格视图数据并取消选择单元格
【发布时间】:2012-04-26 00:18:06
【问题描述】:

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

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

通过选择和取消选择单元格之后,表格视图出现(在viewDidAppear:)取消选择动画的时间对用户来说是明显不同的(你自己试试,它更慢而且不会感觉很光滑)。

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

【问题讨论】:

    标签: iphone ios cocoa-touch uitableview


    【解决方案1】:

    您可以从- (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];
    

    【讨论】:

    • 感谢您的回复。对于方法1,我应该在哪里添加取消选择行的方法?正如我所提到的,将它添加到viewDidAppear: 对用户来说看起来与标准行为明显不同,例如,联系人应用程序(取消选择动画开始较慢)。方法 2 不起作用,因为我在 viewWillAppear: 中为表视图控制器调用 reloadData。用户不会看到取消选择动画。刷新表格视图中的数据是否有更好的做法?我需要它来显示更新的数据,但也需要取消选择动画。
    • 如果您只是重新加载更改的行而不是整个表怎么办?
    • 这似乎达到了预期的效果!但是为什么这行得通,而用[[self tableView] reloadData]; 替换第一行却不行?表格视图是否以不同的方式重绘?
    • @ibeitia 请看看我的问题。 stackoverflow.com/questions/21126654/…
    【解决方案2】:

    更高级的解决方案:

    • 它适用于[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
    

    【讨论】:

      猜你喜欢
      • 2019-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-10
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多