KimJitae
KimJitae

Reputation: 265

swift UIViwe.animate not work in UITableViewCell

enter image description here

I made an animation that moves an orange View when a button is pressed.

blue = UIButton, orange = animation target View

for button in toggleButtons {
        button.addTarget(self, action: #selector(toggleButtonAction), for: .touchUpInside)
}

I created 3 buttons and wrote logic to move them to the position of the buttons, but the orange view moves, but no animation is applied.

@objc func toggleButtonAction(_ sender: UIButton) {
    self.toggleLeading.constant = sender.frame.width * CGFloat(sender.tag)
    UIView.animate(withDuration: 3, delay: 0, options: .curveEaseIn, animations: {
        self.layoutIfNeeded()
    }, completion: nil)
}

The code above is my animation code. It works fine in other UIViewControllers, but it doesn't work in the Custom TableviewCell.

When the button is pressed, the orangeView moves, but it moves like a teleportation rather than an animation.

Upvotes: 0

Views: 130

Answers (1)

Fabio Felici
Fabio Felici

Reputation: 2916

I think we need more code to see why is not working for you but I quickly tried this on a playground and seems to be working fine:

import PlaygroundSupport
import UIKit

class MyCell: UITableViewCell {

  private var leadingConst: NSLayoutConstraint!

  override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

    let view = UILabel()
    view.text = "Move view"
    view.backgroundColor = .orange
    view.translatesAutoresizingMaskIntoConstraints = false

    let buttons: [UIButton] = (0...2).map {
      let button = UIButton()
      button.backgroundColor = .blue
      button.tag = $0
      button.setTitle("\($0 + 1)", for: .normal)
      button.addTarget(self, action: #selector(onTap), for: .touchUpInside)
      return button
    }

    let stackView = UIStackView(arrangedSubviews: buttons)
    stackView.distribution = .fillEqually
    stackView.axis = .horizontal
    stackView.translatesAutoresizingMaskIntoConstraints = false
    contentView.addSubview(stackView)
    contentView.addSubview(view)

    leadingConst = view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 0)

    NSLayoutConstraint.activate([
      leadingConst,
      view.heightAnchor.constraint(equalToConstant: 25),
      view.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 1 / 3),
      view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
    ])

    NSLayoutConstraint.activate([
      stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
      stackView.topAnchor.constraint(equalTo: contentView.topAnchor),
      stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
      stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
    ])
  }

  required init?(coder: NSCoder) {
    nil
  }

  @objc func onTap(_ sender: UIButton) {
    self.leadingConst.constant = sender.frame.width * CGFloat(sender.tag)
    UIView.animate(withDuration: 3, delay: 0, options: .curveEaseIn, animations: {
      self.contentView.layoutIfNeeded()
    }, completion: nil)
  }
}

class ViewController: UITableViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(MyCell.self, forCellReuseIdentifier: "MyCell")
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    10
  }

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath)
  }

  override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    50
  }

  override func numberOfSections(in tableView: UITableView) -> Int {
    1
  }
}

PlaygroundPage.current.liveView = ViewController()

gif

Upvotes: 1

Related Questions