插入新表行后,UITableView节页脚移动

Tim*_*ean 5 uitableview uikit ios

我有一个显示项目列表的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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

    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
    }
Run Code Online (Sandbox Code Playgroud)

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

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

这一切都很好,但是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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

我在insertRowsAtIndexPaths这里使用不正确吗?

HMH*_*ero 6

我认为这种情况正在发生,因为缺少beginUpdates()和endUpdates(),这将是非常简单的错误.但是当我测试它时,我遇到了完全相同的问题.

我将分享我的观察.

当我尝试使用tableview样式Grouped时,上面的问题没有发生.但是,如果我使用普通样式,页脚将下降到tableview的底部.我猜这与不同的页脚视图行为有关,具体取决于它的样式以及更新数据后表格视图布局其内容的方式.

如果必须使用具有Plain样式的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 
}
Run Code Online (Sandbox Code Playgroud)

为了使一切变得干净,你应该了解tableview的section footer/header的行为及其不同的样式和框架.希望您能找到符合您要求的更好的解决方案.