Swift: Как оживить rowHeight UITableView?

Я пытаюсь оживить высоту таблиц tableViewCell, вызвав startAnimation() внутри функции tableView:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TableViewCell

    tableView.rowHeight = 44.0

    startAnimation(tableView)

    return cell
}

//MARK: Animation function

func startAnimation(tableView: UITableView) {

    UIView.animateWithDuration(0.7, delay: 1.0, options: .CurveEaseOut, animations: {

        tableView.rowHeight = 88.0

    }, completion: { finished in

        print("Row heights changed!")
    })
}

Результат: высота строки изменяется, но без какой-либо анимации. Я не понимаю, почему анимация не работает. Должен ли я, возможно, определить какое-то начальное и конечное состояние?

Ответ 1

Не меняйте высоту таким образом. Вместо этого, когда вы знаете, что хотите изменить высоту ячейки, вызовите (в любой функции):

self.tableView.beginUpdates()
self.tableView.endUpdates()

Эти вызовы уведомляют tableView, чтобы проверить изменения высоты. Затем выполните делегат override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat и укажите правильную высоту для каждой ячейки. Изменение высоты будет анимировано автоматически. Вы можете вернуть UITableViewAutomaticDimension для элементов, у которых нет явной высоты для.

Я бы не предлагал делать такие действия из cellForRowAtIndexPath, однако, но в одном, который отвечает, например, нажатием didSelectRowAtIndexPath. В одном из моих классов я:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath == self.selectedIndexPath {
      self.selectedIndexPath = nil
    }else{
      self.selectedIndexPath = indexPath
    }
  }

internal var selectedIndexPath: NSIndexPath? {
    didSet{
      //(own internal logic removed)

      //these magical lines tell the tableview something up, and it checks cell heights and animates changes
      self.tableView.beginUpdates()
      self.tableView.endUpdates()
    }
  }

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if indexPath == self.selectedIndexPath {
      let size = //your custom size
      return size
    }else{
      return UITableViewAutomaticDimension
    }
  }

Ответ 2

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TableViewCell

    tableView.rowHeight = 44.0

    UIView.animateWithDuration(0.7, delay: 1.0, options: .CurveEaseOut, animations: {

        tableView.rowHeight = 88.0
        cell.layoutIfNeeded()

    }, completion: { finished in

        print("Row heights changed!")
    })

    return cell
}