【问题标题】:New solution to detect tableView reloadData completion?检测 tableView reloadData 完成的新解决方案?
【发布时间】:2013-04-26 16:58:21
【问题描述】:

我需要检测 tableview 何时完成重新加载数据。有一个较旧的解决方案,您可以将 tableview 子类化,然后重载 reloadData 方法,但显然不再有效,因为现在在多个线程上处理表,并且在 cellForRowAtIndexPath 之前调用了 reloadData。

我的问题是,自从更改以来,这个问题是否有任何解决方案?

我的问题是,当表重新加载其数据时,我丢失了指向 textField 的指针,因此我尝试设置为下一个文本字段(以自动关注下一个数据输入字段)的第一响应者丢失了。

【问题讨论】:

  • 这个answer 会为您服务吗?
  • 你是如何创建这个指针的?您应该发布一些关于如何创建和使用它的代码。您的问题的解决方案可能不涉及检测 viewDidLoad 的完成。
  • 我并没有真正创建它,它使用TextFieldShouldReturn 委托方法中给我的指针设置了第一响应者。但是在调用此委托后表格会刷新,并且我丢失了指针。或者,我怀疑这是正在发生的事情,因为我将第一响应者设置为正确的文本字段(我检查了我设置它的指针)但是在用户点击返回后焦点丢失了。
  • 如果您正在重新加载表格,那么即使您仍然拥有它,指针也是无效的,因为文本字段所在的表格单元格可能已移动(已回收)。
  • @Wain 那么设置第一响应者,然后刷新表格并将该文本字段维护为第一响应者的解决方案是什么?

标签: ios objective-c uitableview


【解决方案1】:

这基本上是对@wain 答案的重复,但我想我会添加一些代码。

您可以保留对拥有活动文本字段的单元格的索引路径的引用(作为属性)。

然后,在 cellForRowAtIndexPath: 中是这样的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    //I would hold a reference to the text field as a property on a subclass of UITableViewCell so that you can check for whether it exists.

    if (!cell.textField) {

            cell.textField = [[UITextField alloc] initWithFrame:cell.contentView.frame];

            [cell.contentView addSubview:cell.textField];
        }

    return cell;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    UITableViewCell *cell = (UITableViewCell *)textField.superview.superview;

    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

    self.indexPathForActiveTextField = indexPath;
 }

- (BOOL) textFieldShouldReturn:(UITextField *)textField
{
    MyTableViewCell *cell = (MyTableViewCell *)textField.superview.superview;

    NSIndexPath *ip = [self.tableView indexPathForCell:cell];

    [self.tableView reloadData];

    NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:ip.row+1 inSection:ip.section];

    MyTableViewCell *theNewCell = (MyTableViewCell *)[self.tableView cellForRowAtIndexPath:nextIndexPath];

    if (theNewCell) {

        [theNewCell.textField becomeFirstResponder];
    }

    return YES;
}

【讨论】:

  • 这个解决方案对我不起作用,我猜这些子类单元格和文本字段的设置方式。我将第一响应者设置为正确的文本字段,但焦点从未转移。任何文本字段的焦点都会完全消失。
  • @JMD,使用经过测试且有效的解决方案进行编辑。看起来 cellForRowAtIndexPath 不是调用 becomeFirstResponder 的地方。但是您可以在 textFieldShouldReturn 中获取重新加载的自定义 UITableViewCell 的 textField 属性(或任何应该通过您的单元格推进的方法),然后在那里调用 becomeFirstResponder。
【解决方案2】:

存储应该是第一响应者的文本字段的表格单元格的NSIndexPath。当您想更改第一响应者时,您可以向表格视图询问该索引路径处的单元格,然后找到文本字段并将其设为第一响应者。

如果表格视图重新加载,请在 cellForRowAtIndexPath: 检查索引路径并使“新”文本字段成为第一响应者。

通过这种方式,您可以随时设置第一响应者,并且您不能丢失对它的引用,因为引用是指向位置,而不是对象(将被重用或删除)。

【讨论】:

    【解决方案3】:

    UITableView 使用一个池来重用显示的单元格。目标单元格可能在其他行中重复使用。像 Wain 建议的那样存储 NSIndexPath 是很好的,直到您不重新排序单元格或从数据源中删除某些条目。在模型中定义一个键,根据该键设置 firstResponder 。希望我没有误解这个问题。

    【讨论】:

      猜你喜欢
      • 2013-09-08
      • 1970-01-01
      • 2016-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2023-03-04
      相关资源
      最近更新 更多