动画化tableview高度约束,但动画正在跳跃

时间:2018-07-23 03:59:25

标签: ios swift uitableview

我想为我拥有的表格视图设置高度限制。我已经建立了一个小型测试项目。表格视图位于容器视图中。

enter image description here

我的代码如下:

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var heightConstraint: NSLayoutConstraint!
    @IBOutlet weak var contentView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
    }

    @IBAction func didTapAnimate(_ sender: Any) {
        heightConstraint.constant = 400
        UIView.animate(withDuration: 1.0, animations: {() in
            self.contentView.layoutIfNeeded()
        })
    }

}

extension ViewController: UITableViewDataSource {

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

}

extension ViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.backgroundColor = UIColor.red
        return cell
    }

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

}

问题是,当我按下动画按钮时,动画无法顺利进行。桌子首先跳到一定高度,然后为其余部分设置动画。此处的示例:

enter image description here

我在这里做错了什么?桌子为什么跳?我需要动画流畅。任何提示或指针对此将不胜感激!谢谢!

3 个答案:

答案 0 :(得分:1)

因为使用了高度Constraint.constant = 400,所以高度要变大,因此需要使用约束位置“ Y”并移动到位置Y

  UIView.animate(withDuration: 1.0, animations: {
        self.yourTable.frame = CGRect(x: self.yourTable.frame.origin.x, y: self.view.frame.height - self.yourTable.frame.height - <Where do you want go>, width: self.yourTable.frame.width, height: self.yourTable.frame.height) 
    })

答案 1 :(得分:1)

添加到tableview的约束在您的方案中有冲突。检查storyboard中的内容。

我使用了与您相同的代码:

@IBAction func methodAnimate(_ sender: Any) {
    heightConstraint.constant = 400
    UIView.animate(withDuration: 1.0, animations: {() in
        self.contentView.layoutIfNeeded()
    })
}

有这些限制:

enter image description here

动画效果很好。

答案 2 :(得分:1)

因此,您的问题不是动画,而是UITableView的重新加载。表格视图仅包含可见的单元格,并且会加载大约等于顶部和底部单元格高度的附加单元格。但是您的身高增长得如此之多,以至于必须重新加载才能保持可见的单元格,从而使重新加载和表格看起来跳动起来。因此,我将如何处理此问题,方法是先从表格视图的顶部向底部安全区域插图添加一个附加约束,该约束反比于您的高度约束。一分钟后,您将明白为什么会这样。抱歉,我退出了内容视图,但所有视图应该都一样。

topConstraint 这是整个设置的图像。 completesetup

现在有了代码和技巧。诀窍是,当放大表格视图时,您首先要在没有动画的情况下进行操作,但不要将其向上移动。然后,为刚刚添加的等于-height的最高约束设置动画。这样,用户看不到重新加载,但是看起来重新增长。要使其更小,您可以将其向下移动,然后更改大小,以使用户永远不会看到重新加载。这是代码,我添加了注释以帮助您了解我在说什么。

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var topTableConstraint: NSLayoutConstraint!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var heightConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
    }

    @IBAction func didTapAnimate(_ sender: Any) {

        if heightConstraint.constant != 400{
            //first change the height.  The thing that will happen is allow the tableview to load up all of it's rows and will stop the choppy ness
            heightConstraint.constant = 400
            self.view.layoutIfNeeded()
            //now we can move it up and it will appear to grow.
            //with iphone x i would put a view in inside the safearaa above the table as to now see it slide up or load underneath or you could pin your content view to the safe area and clip to bounds and this would work as well
            topTableConstraint.constant = -heightConstraint.constant
            UIView.animate(withDuration: 1.0) {
                self.view.layoutIfNeeded()
            }
        }else{
           //animating down so let's do the reverse order
            topTableConstraint.constant = -100
            UIView.animate(withDuration: 1.0, animations: {
                self.view.layoutIfNeeded()
            }) { (finished) in
                self.heightConstraint.constant = 100
                self.view.layoutIfNeeded()
            }
        }
    }

}

extension ViewController: UITableViewDataSource {

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

}

extension ViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.backgroundColor = UIColor.red
        return cell
    }

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

}

结果将如下所示。希望对您有所帮助,并为您解决问题。

Result

如果您希望所有单元格都变成红色,则需要注册一个单元格,方法是使用dequeueReusableCell而不是创建新单元格。