iOS 如何動畫改變約束

當咱們使用 frame 佈局控件的時候,若是控件的 frame 發生改變時,咱們想讓改變產生動畫過渡效果,而不是生硬的直接改變。咱們可使用 UIView 的 animate(withDuration:animations:completion:) 函數來實現,以下面的代碼:bash

UIView.animate(withDuration: 0.5) {
     // 改變後的frame
    self.exampleView.frame = CGRect(x: 10, y: 10, width: 100, height: 100)
}
複製代碼

那當咱們使用 AutoLayout 佈局的時候,咱們想實現上面的效果該如何寫呢?ide

經過下面的兩個步驟咱們就能夠實現:函數

  • 改變目標控件約束
  • 調用 animate(withDuration:animations:completion:) 函數
    • 調用目標控件父視圖的 layoutIfNeeded() 函數

具體例子

聲明全局變量

private let exampleView = UIView(frame: .zero)
private var topConstraint = NSLayoutConstraint()
複製代碼

使用 AutoLayout 佈局控件

extension ViewController {
    private func setupSubviews() {
        
        exampleView.backgroundColor = .green
        view.addSubview(exampleView)
        
        exampleView.translatesAutoresizingMaskIntoConstraints = false
        topConstraint = exampleView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100)
        topConstraint.constant = 100
        NSLayoutConstraint.activate([
            topConstraint,
            exampleView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 100),
            exampleView.widthAnchor.constraint(equalToConstant: 100),
            exampleView.heightAnchor.constraint(equalToConstant: 100)
            ])
        
        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 100, y: 400, width: 100, height: 50)
        button.backgroundColor = .red
        button.addTarget(self, action: #selector(buttonAction(_:)), for: .touchUpInside)
        view.addSubview(button)
    }
}
複製代碼

動畫改變約束

extension ViewController {
    @objc func buttonAction(_ sender: UIButton) {
        // 修改約束
        topConstraint.constant = 200
        //調用父視圖的 layoutIfNeeded()
        UIView.animate(withDuration: 0.5) {
            self.view.layoutIfNeeded()
        }
    }
}

複製代碼

效果圖 - 動畫改變約束

注意事項

  • 在要調用目標控件的父視圖layoutIfNeeded() 函數
  • 注意調用的是 layoutIfNeeded() 函數,不是 setNeedsLayout()
  • 參考
相關文章
相關標籤/搜索