UITableView - 如何使用全新数据重新加载?

时间:2014-11-12 21:27:03

标签: ios uitableview

我有一个显示搜索输出的表格视图。当我更新它以显示完全不同的搜索的输出时,如果旧的结果集更长,那么旧单元格仍然低于我的新单元格。

例如,如果我的第一个结果是:

[Sam,
Joe,
Sally,
Betty,
Bob]

然后我有五个单元格,每个结果一个,如预期的那样。如果我的第二组结果很短,请说

[Smith]

然后我现在有五个单元格( Smith ,Joe,Sally,Betty和Bob),当时只有一个(Smith)。

这是我如何重装:

results = getResults()
tableView.reloadData()

以下是我获取细胞数量的方法:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if results != nil {
        println("Table has \(results!.count) rows.")
        return results!.count
    }
    println("Table is empty.")
    return 0
}

打印出来"表格有1行。"正如预期的那样,但仍有四个旧行。

现在,我可以在重新加载之前删除它们,或删除整个部分,但有没有更好的方法来实现这一目标?我以为reloadData会重新加载所有内容。


其他信息

这里是请求的cellForRowAtIndexPath:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("SearchEventsCell", forIndexPath: indexPath) as SearchEventsCell
    if results != nil && eventStore != nil && results!.count >= indexPath.row {
        let event = results![indexPath.row] as EKEvent
        cell.configureCellWithEvent(event)
    }
    else {
        println("Couldn't dequeue the cell")
    }
    return cell
}

为了证明我们在reloadData()之前有一个println的正确行数:

println("We're about to reload the table view, we have \(numberOfSectionsInTableView(tableView)) sections and \(tableView(tableView, numberOfRowsInSection:0)) rows in section 0")
tableView.reloadData()

哪个输出

  

表有1行   我们即将重新加载表视图,我们在第0部分中有1个部分和1行   表有1行。

应该如此。

我注意到的其他东西,肯定是必须相关的 - 在我尝试滚动之前,表格根本没有更新。我错过了什么?我知道在numberOfRowsInSection中调用println时调用了reloadData。


更新

触发更新的textFieldShouldReturn方法包括以下代码:

eventStore.requestAccessToEntityType(EKEntityTypeEvent,
    { accessGranted, error in
        if accessGranted {
            if let searchEventsController = self.searchEventsController {
                searchEventsController.search(self.searchTextField.text)
            }
        }
        else {
            self.accessDenied()
        }
    }
)

这似乎很可能是罪魁祸首。有没有更好的方法来检查权限?我把它包含在那里,以便如果用户不允许它,它会在下次尝试使用它时再次询问,而不是仅仅失败。

1 个答案:

答案 0 :(得分:1)

问题确实是由于eventStore.requestAccessToEntityType调用,reloadData正在另一个线程中发生。

有两种解决方案:

1)根据Paulw11的建议,在应用加载时执行一次权限检查,而不是每次访问EventStore时执行权限检查。这意味着对于大多数应用程序而言,只有一个线程。

2)使用以下代码在主线程上执行reloadData:

dispatch_async(dispatch_get_main_queue()) {
    self.tableView.reloadData()
}

如almas所建议。

更新:我刚检查过,如果您取消该应用访问日历的权限,那么无论如何它都不会再次询问用户,它只是拒绝访问,所以没有保留eventStore.requestAccessToEntityType的原因。