UITableView section footer moves after inserting new table rows

I have a UITableView that displays a list of items. The table view controller has an array of elements that updates asynchronously after responding from a web service call. Here is an example of what I have (in 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
    }
}

I want every section of this table to have a footer with a button, so I also include the following:

    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
    }

Elements are added to the array itemsthrough a callback that is called outside the main UI thread. It looks something like this:

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

All this works fine, but my use of the table reloadDataseems redundant to me when I know that only one item is added at a time. So, I tried updating it to do the following:

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)
    }
}

, , . , "", , 0, , 1.

, - , , , . UITableViewController UINavigationController, , , . , .

- reloadData insertRowsAtIndexPaths. , , , .

insertRowsAtIndexPaths ?

+4
1

, , beginUpdates() endUpdates() , . , .

.

Tableview Grouped, . Plain, . , - .

tableview Plain, , ( ) , . - ,

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 . , , .

+6

Source: https://habr.com/ru/post/1570093/


All Articles