1

So I want to change the default animation duration of UITableView's beginUpdates() & endUpdates(), which I think is 0.3s.

I tried placing them inside a UIView animation block, then I got abrupt animation.

To see what I am talking about, create a new iOS "Single View Application" Project, and replace ViewController.swift with the following code:

class ViewController: UIViewController {

    var tableView = UITableView()
    var isExpanded = false

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(tableView)
        tableView.frame = view.bounds
        tableView.dataSource = self
        tableView.delegate  = self

        let changeHeightButton = UIBarButtonItem(title: "Change Height", style: .plain, target: self, action: #selector(changeHeight))
        navigationItem.rightBarButtonItem = changeHeightButton
    }

    func changeHeight() {
        isExpanded = !isExpanded
        UIView.animate(withDuration: 0.5, animations: {
            self.tableView.beginUpdates()
            self.tableView.endUpdates()
        }, completion: nil)
    }
}

extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
        cell.textLabel?.text = "Section \(indexPath.section), Row \(indexPath.row)"
        return cell
    }
    func numberOfSections(in tableView: UITableView) -> Int{
        return 4
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "Section: \(String(section))"
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if isExpanded && indexPath == IndexPath(row: 0, section: 0) { return 300 }
        else { return 44 }
    }
}
  • That's some strange Section Header re-drawing! Looks like `bug` to me... Possible workaround would be to use auto-sizing cells and animate the content instead of the rowHeight? – DonMag Apr 27 '17 at 18:11
  • Thanks for the suggestion. I have limited knowledge on self-sizing cells. What I am trying to do is changing the layout of a cell (by replacing the constraints) when the user taps on one of its views. The new layout need a larger rowHeight. For self-sizing cells to update rowHeight based on the new constraints, do you still need to call beginUpdates() and endUpdates() to animate it? – Jianyi Huang Apr 27 '17 at 20:00
  • You might take a look at my answer here: http://stackoverflow.com/questions/43096231/expand-uilabel-inside-uitableview-with-more-button-like-instagram (it also contains a link to a set of auto-sizing-cells examples I've done) – DonMag Apr 27 '17 at 20:14
  • I downloaded your project, and in `SampleThreePartTableViewController.swift` I added some additional sections and implemented `titleForHeaderInSection`, put beginUpdates() and endUpdates() inside an animation block, scroll down until the added sections are visible, and click "Read more...", same abrupt animation occurred. – Jianyi Huang Apr 27 '17 at 20:33
  • Sorry, yeah... The examples are all using `beginUpdates() / endUpdates()` wrappers... but none are using multiple sections (which seems to be the issue) – DonMag Apr 27 '17 at 20:47

0 Answers0