【问题标题】:UITableView section footer moved after inserting new table rowsUITableView 部分页脚在插入新表格行后移动
【发布时间】:2015-03-03 16:08:05
【问题描述】:

我有一个显示项目列表的 UITableView。表格视图控制器有一组项目,这些项目在响应对 Web 服务的调用时异步更新。这是我所拥有的一个示例(在 Swift 中):

class MyTableViewController : UITableViewController {
    var items: [ItemClass] = []

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("RootCell", forIndexPath: indexPath) as UITableViewCell
        if indexPath.section == 0 {
            let item = items[indexPath.row]
            cell.textLabel!.text = item.name
        }
        else if indexPath.section == 1 {
            // Another section not shown here
        }
        return cell
    }
}

我希望这个表格的每个部分都有一个带有按钮的页脚,所以我还包括这个:

    override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        let button = UIButton.buttonWithType(.System) as UIButton
        button.setTitle("Add", forState:UIControlState.Normal)
        if section == 0 {
            button.addTarget(self, action:Selector("itemAddPressed:"), forControlEvents:UIControlEvents.TouchUpInside)
        }
        else if section == 1 {
            // other section not shown here
        }
        return button
    }

通过在主 UI 线程之外调用的回调将项目添加到 items 数组。它看起来像这样:

private func itemWasAdded(item: ItemClass) {
    dispatch_async(dispatch_get_main_queue()) {
        self.items += [item]
        self.tableView!.reloadData()
    }
}

这一切都很好,但是当我知道一次只添加一个项目时,我对表的 reloadData 的使用对我来说似乎有点矫枉过正。因此,我尝试对其进行更新以执行以下操作:

private func itemWasAdded(item: ItemClass) {
    dispatch_async(dispatch_get_main_queue()) {
        self.items += [item]
        let indexPath = NSIndexPath(forRow:self.item.count - 1, inSection:0)
        self.tableView!.insertRowsAtIndexPaths([indexPath], withRowAnimation: .None)
    }
}

当我这样做时,表格继续工作,但页脚按钮出现问题。我没有显示我在每个部分的页脚中创建的添加按钮,而是在表格视图底部的第 1 部分下方看到了第 0 部分的添加按钮。

似乎做一些事情来强制刷新表格似乎可以解决问题。这个 UITableViewController 是 UINavigationController 中的顶级控制器,如果我选择一个表格单元格,一个新的视图控制器会被推送到导航控制器上。导航回原始表格视图控制器,页脚按钮显示在正确的位置。

完成这项工作的最简单方法是使用reloadData 而不是insertRowsAtIndexPaths。但我想知道我在这里做错了什么,以便尽可能避免重新加载所有表数据。

我在这里错误地使用了insertRowsAtIndexPaths 吗?

【问题讨论】:

  • 在使用 insertRowsAtIndexPaths 时忘记了 beginUpdates 和 endUpdates??
  • 我的印象是它们只在进行批量更新时才需要,在这里我一次只添加一行。不过,我尝试添加 beginUpdates() 和 endUpdates() 以查看它是否解决了问题,但没有任何区别。
  • 这似乎是正确的答案。 stackoverflow.com/questions/5740518/…

标签: ios uitableview uikit


【解决方案1】:

我认为这是因为 beginUpdates() 和 endUpdates() 丢失了,这将是一个非常简单的错误。但是我在测试时遇到了完全相同的问题。

我只是分享我的观察。

当我尝试使用 tableview 样式分组时,上述问题没有发生。但是如果我使用普通样式,页脚会下降到表格视图的底部。我想这与不同的页脚视图行为有关,具体取决于其样式和更新数据后表格视图布局其内容的方式。

如果您必须使用普通样式的 tableview,则必须处理其内容高度(单元格和节页脚视图)的总和小于插入行之前的 tableview 高度的情况。 类似的,

let contentHeight = CGFloat(items.count * cellHeight + numberOfSection*footerHeight)
if contentHeight < tableViewHeight {
   tableView.frame = CGRectMake(0, 0, view.frame.size.width, numberOfSection*CGFloat(items.count * cellHeight + footerHeight))    
} else {
   tableView.frame = viewHeight 
}

为了让一切变得干净,您应该了解 tableview 的节页脚/页眉的行为及其不同的样式和框架。希望您能找到更符合您要求的解决方案。

【讨论】:

  • 谢谢@HMHero - 我仍然不确定为什么会发生这种情况,但是当我使用分组表视图样式时问题消失了,你说得对。为了避免这个问题,我在这里改用了分组样式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-14
相关资源
最近更新 更多