为自定义进度条Autolayout设置动画宽度约束

时间:2017-07-18 18:44:10

标签: ios animation autolayout

我正在尝试创建一个简单的水平进度条视图,我想设置宽度约束的动画。

出于测试目的,我创建了一个按钮,可以在点击时增加进度条的百分比。

当我点击按钮时,宽度约束按预期动画。但是,如果我在初始化组件时尝试设置百分比,则整个视图会动画,这不是我想要的。

class ProgressBar: UIView {
    private let progressView: UIView
    private var progressBarWidth: NSLayoutConstraint? = nil

    var percentage: Double = 0 {
        didSet {
            updateProgress()
        }
    }

    init() {
        progressView = UIView()
        super.init(frame: .zero)
        setupBackgroundBar()
        setupProgressView()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupBackgroundBar() {
        self.heightAnchor.constraint(equalToConstant: 10).isActive = true
        self.backgroundColor = UIColor(colorLiteralRed: 1, green: 1, blue: 1, alpha: 0.5)
    }

    private func setupProgressView(){
        self.addSubview(progressView)
        progressView.translatesAutoresizingMaskIntoConstraints = false

        progressView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        progressView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        progressView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        progressView.backgroundColor = UIColor.white
    }

    func updateProgress() {
        let progressMultiplier = CGFloat(percentage/100)

        UIView.animate(withDuration: 1.0) {
            if let progressConstraint = self.progressBarWidth {
                NSLayoutConstraint.deactivate([progressConstraint])
            }

            self.progressBarWidth = self.progressView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: progressMultiplier)
            self.progressBarWidth?.isActive = true
            self.layoutIfNeeded()
        }
    }
}

查看控制器

class ViewController: UIViewController {
    let progressBar: ProgressBar

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.black

        self.view.addSubview(progressBar)
        progressBar.translatesAutoresizingMaskIntoConstraints = false

        progressBar.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 30).isActive = true
        progressBar.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 30).isActive = true
        progressBar.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -30).isActive = true


        let button = UIButton(type: .roundedRect)
        self.view.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = UIColor.white
        button.setTitleColor(UIColor.black, for: .normal)
        button.setTitle("Increase 1%", for: .normal)

        button.topAnchor.constraint(equalTo: progressBar.bottomAnchor, constant: 10).isActive = true
        button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true

        button.addTarget(self, action:#selector(self.buttonTapped), for: .touchUpInside)
    }

    required init?(coder aDecoder: NSCoder) {
        progressBar = ProgressBar()
        super.init(coder: aDecoder)
    }

    func buttonTapped() {
        progressBar.percentage += 1
    }
}

我想在初始化视图时设置宽度约束的动画,就像点按按钮时一样。

2 个答案:

答案 0 :(得分:1)

尝试在layoutSubviews()中设置进度条的动画。所以这样的事情应该有效:

override func layoutSubviews()
{
 super.layoutSubviews()
 updateProgress()
}

答案 1 :(得分:0)

您可以尝试在viewController的viewDidAppear方法中设置宽度约束的动画。