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

4
我有一个表视图,当从详细视图返回时,我想取消先前选择的单元格或用户创建项目时新添加的单元格的选择。然而,由于有时会添加新项目,因此在viewWillAppear中调用reloadData来刷新表格。这意味着即使我设置了self.clearsSelectionOnViewWillAppear = NO, 当视图出现时,没有任何单元格被选中。如果在表视图出现后(在viewDidAppear中)选择和取消选择单元格,则取消选择动画的时间对用户可见的不同(请自行尝试,速度较慢,感觉不太流畅)。我应该如何保留选择,即使表视图已刷新?(请记住,根据情况,我希望取消先前选择的单元格或新创建的单元格的选择)。或者我应该以某种方式以不同的方式重新加载我的表格数据?
2个回答

7
你可以保存从 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 方法中得到的 NSIndexPath,并在视图重新加载时取消选择该行。
另一种方法是将 NSIndexPath 和当前的 UITableViewController 传递给你正在创建的 UIViewController,当那个 UIViewController 被弹出时,你可以取消选择特定的行。
当创建一个新项目时,将索引路径的行元素加一以取消选择正确的行。
你也可以仅重新加载已更改的行。
[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。用户将看不到取消选择动画。是否有更好的实践方法来刷新我的表视图数据?我需要它显示更新的数据,但也希望取消选择动画。 - James
如果只重新加载更改的行而不是整个表,会怎样呢? - Iñigo Beitia
1
这似乎产生了期望的效果!但是为什么用[[self tableView] reloadData];替换第一行不起作用呢?表格视图被重新绘制了吗? - James
@ibeitia 请看一下我的问题。http://stackoverflow.com/questions/21126654/uitableview-deselects-tableviewcells-when-scrolling-away-and-back - Chisx

0
更高级的解决方案:
  • 它可以与[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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接