【问题标题】:Is there a way to animate autolayout constraints using an autolayout extension programmatically?有没有办法以编程方式使用自动布局扩展为自动布局约束设置动画?
【发布时间】:2019-11-18 18:42:31
【问题描述】:
  • 我正在完全以编程方式创建此应用

我想将 addButton 从右下角动画到 headerLabel 的 centerYAnchor,最好使用这个自动布局扩展(下面的扩展)。

view.addSubview(headerLabel)
    headerLabel.setAnchors(top: view.topAnchor, paddingTop: 50, bottom: nil, paddingBottom: 0, left: view.leftAnchor, paddingLeft: 40, right: view.rightAnchor, paddingRight: 40, centerX: nil, centerY: nil, width: 0, height: 0)

view.addSubview(addButton)
    addButton.setAnchors(top: nil, paddingTop: 0, bottom: view.bottomAnchor, paddingBottom: 16, left: nil, paddingLeft: 0, right: view.rightAnchor, paddingRight: 16, centerX: nil, centerY: nil, width: 60.0, height: 60.0)

当用户点击按钮时,我希望按钮的 centerYAnchor 向上动画并匹配 headerLabel 的 centerYAnchor。

@objc func addListButtonClicked(sender : UIButton){
    UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseIn, animations: {


    })
}

谁能帮我解决这个问题,或者给我一些从哪里开始的方向?谢谢!

【问题讨论】:

标签: ios swift animation autolayout programmatically


【解决方案1】:

一种方法:

为您的addButton 使用“开始”和“结束”约束变量,然后根据您想要按钮的位置激活/停用它们。

var startConstraint: NSLayoutConstraint!
var endConstraint: NSLayoutConstraint!

override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(addButton)

    // set ONLY right anchor, width and height
    addButton.setAnchors(top: nil, paddingTop: 0, bottom: nil, paddingBottom: 0, left: nil, paddingLeft: 0, right: view.rightAnchor, paddingRight: 16, centerX: nil, centerY: nil, width: 60.0, height: 60.0)

    // define "starting location" constraint
    // bottom of addButton 16-pts from bottom of view
    startConstraint = addButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -16.0)

    // define "ending location" constraint
    // centerY of addButton at centerY of headerLabel
    endConstraint = addButton.centerYAnchor.constraint(equalTo: headerLabel.centerYAnchor)

    // activate the starting constraint
    startConstraint.isActive = true

}

然后,当您想要将按钮动画到 headerView 时:

@objc func addListButtonClicked(sender : UIButton) {

    // deactivate the start constraint      
    startConstraint.isActive = false

    // activate the end constraint 
    endConstraint.isActive = true

    UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseIn, animations: {
        self.view.layoutIfNeeded()
    })

}

这还允许您通过颠倒顺序和激活状态将按钮动画化回其原始位置:

    // moves button from bottom up to header view
    startConstraint.isActive = false
    endConstraint.isActive = true

    // moves button from header view down to bottom
    endConstraint.isActive = false
    startConstraint.isActive = true

【讨论】:

    【解决方案2】:

    你可以试试

    // remove old bottom constraint 
    self.view.constraints.forEach {
       if $0.firstItem == self.addButton && $0.firstAttribute == .bottom  {
           self.view.removeConstraint($0)
       }
    } 
    
    // add a new centerY
    self.addButton.centerYAnchor.constraint(equalTo:self.headerLabel.centerYAnchor).isActive = true 
    
      UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseIn, animations: { 
          self.view.layoutIfNeeded()
      })
    

    您也可以这样做(不建议将自动布局与框架混合使用)

      UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseIn, animations: { 
          self.addButton.center = self.headerLabel.center
      })
    

    【讨论】:

      猜你喜欢
      • 2015-12-26
      • 2014-05-26
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多