通过 reloadData 更新 UITableView 时保持选择

Posted

技术标签:

【中文标题】通过 reloadData 更新 UITableView 时保持选择【英文标题】:Keeping selection upon updating UITableView via reloadData 【发布时间】:2012-04-05 04:44:54 【问题描述】:

我正在尝试实现一个类似于 Apple 日历应用程序设置开始时间和结束时间视图的视图。我的观点看起来很棒,但我遇到了两个问题。首先,我想自动选择第一行。我有点用这个工作:

NSIndexPath *indexPath=[NSIndexPath indexPathForRow:0 inSection:0];
[dateTableView selectRowAtIndexPath:indexPath animated:YES  scrollPosition:UITableViewScrollPositionBottom];

但是,动画显示,在加载视图时可视选择行,我希望在加载视图时已经选择它。

第二个也是更重要的问题是,当我在选择器更新后重新加载数据时,我失去了选择,我的任务根本不起作用。

现在我知道这是 reloadData 的默认操作,我正在寻找一种替代方法来实现我的目标,或者我可以如何增加 reloadData 以不取消选择当前选择。

我的任务如下:

-(IBAction)dateChanged


   NSIndexPath *index = self.dateTableView.indexPathForSelectedRow;
    if(index == 0)
    
        if (self.date2 == plusOne ) 
            self.date = [datePicker date];
            plusOne = [self.date dateByAddingTimeInterval:60*60];
            self.date2 = plusOne;
        
        else
        
            self.date = [datePicker date];
        

    
    else
        self.date2 = [datePicker date];
    

    [dateTableView reloadData];

注意:plusOne 是一个变量,最初表示距当前时间一小时。

提前致谢!

【问题讨论】:

你用什么方法调用你的第一个代码块? 【参考方案1】:

对于第一个问题,在方法调用上设置动画:NO。您当前将其设置为 YES。

[dateTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionBottom];

对于第二个问题,您在重新加载数据后尝试选择什么并不十分清楚,但我发现这一行存在问题:

    if(index == 0)

您是在询问指向对象的指针是否为 0。我认为您想要的是检查 index == nilindex.section == 0 && index.row == 0 或类似的东西。

无论如何,如果您在 UITableView 上调用 reloadData,您将失去选择。此时,您需要选择一个新行。如果您想要选择数据模型中的某个项目,您需要确定它在哪里并根据它在表中的位置选择它(您应该知道这一点,因为您在 UITableViewDataSource 委托中提供了该信息方法。)。或者,如果要选择dateChanged第一行保存的NSIndexPath,重新加载数据后选择即可。

【讨论】:

谢谢!不敢相信我错过了! 太棒了,能够根据您所说的解决问题。添加 index.row 并在没有动画的 reloadData 后重新选择。非常感谢,你摇滚! @BrianCooley 在哪里写datatableview行??【参考方案2】:

对于第一个问题,将代码写入 didSelectRowAtIndexPath: 方法中。然后您可以从 didSelectRowAtIndexPath 调用此方法:您应该将 indexPath 作为参数传递给您的函数,例如,

-(void)doActionsInDidSelectRow:(NSIndexPath*)indexPath
     // write code.

在 viewDidLoad 中调用这个方法

-(void)viewDidLoad

        NSIndexPath *indexPath=[NSIndexPath indexPathForRow:0 inSection:0];
        [dateTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];
        [self doActionsInDidSelectRow:indexPath];
 

对于第二个问题,我的建议是,每次当您选择一个单元格时,将该单元格的文本存储在一个 NSString 中。当您重新加载数据时,在 cellForRowAtIndexPath: 内只需将单元格的文本与您之前存储的字符串内容进行比较。如果它们相等,只需使用

进行选择
[dateTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];

方法。希望这能解决您的问题。

【讨论】:

以上是关于通过 reloadData 更新 UITableView 时保持选择的主要内容,如果未能解决你的问题,请参考以下文章

在 reloadData 后未调用 cellForRowAtIndexPath

reloadData() 不会更新父 TableView

reloadData() 不更新单元格标签

调用 reloadData 后防止标头更新?

在 UICollectionView 上调用 reloadData 后 contentSize 未更新

UICollectionView 在调用 reloadData 时不会立即更新,而是在 30-60 秒后随机更新