Анимация Swift Spring не работает должным образом на UITableViewCell - PullRequest
0 голосов
/ 29 января 2020

Я уже читал некоторые вопросы и не совсем правильно использую весеннюю анимацию в Swift, но меня немного смущает этот случай. У меня есть ViewController, который имеет UITableView. Я хотел бы добавить небольшую анимацию подпрыгивания весны в его ячейки. Когда ячейка коснулась, она должна была развернуться и запустить подпрыгивающую анимацию, и она отлично работает впервые. Но после того, как ячейка развернута и снова нажата, анимация игнорируется, но код внутри animations отлично работает (например, команда печати). Есть ли у вас идеи достичь этой цели, чтобы анимация работала дважды или больше? Я думаю, что теоретически что-то упустил.

Мой ViewController:

class TestTableViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    var selectedIndex: IndexPath = IndexPath(row: 0, section: 0)

    var isExpanded = [Bool]()

    var currentExpandedIndexPath: IndexPath?


    override func viewDidLoad() {
        super.viewDidLoad()

        isExpanded = Array(repeating: false, count: 15)

        tableView.delegate = self
        tableView.dataSource = self

    }
}

extension TestTableViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 15
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestTableViewCell", for: indexPath) as! TestTableViewCell

        cell.selectionStyle = .none
        cell.animate(duration: 0.5, delay: 0.2, damping: 0.5, options: .curveEaseOut)

        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if isExpanded[indexPath.row] == true { return 300 }
        return 150
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {


        // This is just for handling that to be only one cell that is expanded at one time
        isExpanded[indexPath.row] = !isExpanded[indexPath.row]
        if (currentExpandedIndexPath != nil) {
            if (indexPath == currentExpandedIndexPath) {
                currentExpandedIndexPath = nil
            } else {
                isExpanded[currentExpandedIndexPath!.row] = false
                currentExpandedIndexPath = indexPath
            }
        } else {
            currentExpandedIndexPath = indexPath
        }

        tableView.beginUpdates()
        tableView.reloadRows(at: [indexPath], with: .automatic)
        tableView.endUpdates()
    }
}

И это мой класс TableViewCell:

class TestTableViewCell: UITableViewCell {

    func animate(duration: TimeInterval, delay: TimeInterval, damping: CGFloat, options: UIView.AnimationOptions = []) {

        UIView.animate(withDuration: duration, delay: delay, usingSpringWithDamping: damping, initialSpringVelocity: 1,  options: options, animations: {
            self.contentView.layoutIfNeeded()
            print("this command runs everytime")
        })
    }

}

Эти ссылки представляют собой GIF-файлы, которые показывают, как это работает сейчас же. Если я коснусь другой ячейки после того, как одна развернута, у нее будет правильная анимация (первая ссылка). Но если я коснусь расширенной, она не будет анимированной (вторая ссылка).

Нажатие один за другим развернуто

Нажатие на ту же ячейку после того, как она расширен

1 Ответ

0 голосов
/ 30 января 2020

Здесь есть две возможности:

1 - следующий код возможно переопределяет вашу анимацию:

tableView.reloadRows(at: [indexPath], with: .automatic)

Попробуйте передать .none или какой-либо другой флаг.

2 - следующий код должен вызываться из основного потока, также известного как DispatchQueue.main.

self.contentView.layoutIfNeeded()

Также существует 3-я возможность, что reloadRows не обязательно вызывает cellForRowAt там, где вы находитесь в настоящее время обрабатывает анимацию.

...