【问题标题】:How to detect when UITableView has finished loading all the rows? [duplicate]如何检测 UITableView 何时完成加载所有行? [复制]
【发布时间】:2016-03-03 16:15:56
【问题描述】:

我需要在 UITableView 完全加载后调用一个函数。我知道,在大多数情况下,第一次加载视图时不会显示每一行,但在我的情况下,它会显示,因为我总共只有 8 行。

烦人的是被调用的函数需要访问一些tableView的数据,所以在表格加载完成之前不能调用,否则会报错。

在 viewDidAppear 中调用我的函数会损害用户体验,因为此函数会更改 UI。将其放入 viewWillAppear 会破坏执行(我不知道为什么)并将其放入 viewDidLayoutSubviews 效果非常好,但是每次布局更改时都会调用它,我担心在重新加载时可能会出现一些错误表格视图。

我发现关于这个主题的帮助很少。尝试了我在这里找到的一些东西,但不幸的是它没有工作,因为它似乎有点过时了。可能的重复帖子的解决方案不起作用,我在此处发布之前尝试过。

感谢任何帮助!谢谢。

编辑:我正在用一些数据填充我的 tableView,我对此没有任何问题。我有 2 个部分,每 4 行。默认情况下,用户只能看到 5 行(第一部分中的 4 行,第二部分中只有一个,其余部分被隐藏)。当用户单击第一部分的第一行时,它会显示第二部分的第一行。当他单击第一部分的第二行时,它会显示第二部分的两行,依此类推。如果用户随后再次单击第一部分的第一行,则仅显示第二部分中的一个单元格。然后他可以保存他的选择。

同时,系统会更改第一部分中所选行的颜色,以便用户知道该怎么做。

我的部分问题是我想更新数据库中的模型。如果用户想要修改记录,那么我需要将存储在我的数据库中的值与 ViewController 相关联。因此,例如,如果他当时选择了选项 2,我需要确保第一部分中的第二行具有不同的颜色,并且当他尝试访问视图时显示第二部分中的两行。

这里有一些代码:

    func setNonSelectedCellColor(indexPath: NSIndexPath) {
    let currentCell = tableView.cellForRowAtIndexPath(indexPath)
    currentCell?.textLabel?.textColor = UIColor.tintColor()

    for var nbr = 0; nbr <= 3; nbr++ {
        let aCell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: nbr, inSection: 0))
        let aCellIndexPath = tableView.indexPathForCell(aCell!)
        if aCellIndexPath?.row != indexPath.row {
            aCell?.textLabel?.textColor = UIColor.blackColor()
        }
    }
}

func hideAndDisplayPriseCell(numberToDisplay: Int, hideStartIndex: Int) {
    for var x = 1; x < numberToDisplay; x++ {
        let priseCell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: x, inSection: 1))
        priseCell?.hidden = false
    }
    if hideStartIndex != 0 {
        for var y = hideStartIndex; y <= 3; y++ {
            let yCell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: y, inSection: 1))
            yCell?.hidden = true
        }
    }
}

每次用户触摸一行时都会调用这两个函数:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let path = (indexPath.section, indexPath.row)
    switch path {
    case(0,0):
        setNonSelectedCellColor(indexPath)
        hideAndDisplayPriseCell(1, hideStartIndex: 1)
        data["frequencyType"] = Medecine.Frequency.OneTime.rawValue
    case(0,1):
        setNonSelectedCellColor(indexPath)
        hideAndDisplayPriseCell(2, hideStartIndex: 2)
        data["frequencyType"] = Medecine.Frequency.TwoTime.rawValue
    case(0,2):
        setNonSelectedCellColor(indexPath)
        hideAndDisplayPriseCell(3, hideStartIndex: 3)
        data["frequencyType"] = Medecine.Frequency.ThreeTime.rawValue
    case(0,3):
        setNonSelectedCellColor(indexPath)
        hideAndDisplayPriseCell(4, hideStartIndex: 0)
        data["frequencyType"] = Medecine.Frequency.FourTime.rawValue

    default:break
    }

}

我将值存储在字典中,以便在他保存时处理验证。

我希望在我的 tableView 完成加载后立即调用前两个函数。例如,当我初始化第一行时,我不能要求数据源显示/隐藏 1 行或更多行,因为它们尚未创建。

正如我所说,如果在 viewDidAppear 中调用这些函数,这几乎可以正常工作,因为它不会立即选择行,也不会尽快在第二部分中显示适当数量的行。我必须等待 1-2 秒才能完成。

【问题讨论】:

  • 您能提供更多信息吗?错误是什么?另外,也许一些相关的代码?
  • 看不出这样做的原因。您应该已经知道初始化表格单元格时需要的所有数据。
  • 这不是重复的。我尝试了上述方法,但这对我来说效果不佳。
  • 在副本中走得更远一点:我已经尝试过这种方法,但它根本不适合我想做的事情。如果我调用我的一个函数,我会得到一个fatal error: unexpectedly found nil while unwrapping an Optional value,因为调用与 tableView 相关的任何内容时都会返回 nil。例如,let aCell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: nbr, inSection: 0)) 返回 nil,即使它已经创建,我也不知道为什么它是 nil。
  • 您不需要知道表格何时显示,用户与表格行的交互会导致您更新表格显示。您相应地更新您的数据模型并调用表更新函数,例如reloadRowsAtIndexPathsreloadSections。您处理cellForRowAtIndexPath 中单元格的格式。不要循环遍历单元格并直接更新它们。不要设置隐藏属性;为numberOfRowsInSection返回适当的值

标签: ios objective-c swift uitableview


【解决方案1】:

如果您已经拥有用于填充 tableView 的数据,那么您不能在函数中使用该数据本身吗?我假设数据是您在表格视图中显示的对象数组的形式。因此,您已经可以访问该数据并且可以在函数中使用它。

但如果情况并非如此,并且如果您的表格视图只有 8 行,那么您可以尝试实现此函数并在其中检查 indexPath.row == 7(第 8 行是最后一行)。

tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)

由于您的所有行都在一个屏幕上可见而无需滚动,您可以使用此函数来确定所有单元格都已加载,然后调用您的函数。

【讨论】:

  • 它没有被我调用。根据文档,该委托将检测何时从 tableView 中删除了一行。
  • 您是否只使用自定义数据源,didenddisplaying 是从 tableview 委托 set tableview.delegate 中调用它的方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
相关资源
最近更新 更多