iOS 給 storyboard 建立的 view 新增動畫效果
阿新 • • 發佈:2018-11-08
使用 storyboard, xib 建立的檢視, 檢視的約束是用的 Autolayout , 所以實現動畫效果也要通過改變約束的值,而不是直接改變 frame
示例: 在控制器上新增一個 blueView, blueView 上新增一個 greenView, 現改變 blueView 的寬度實現動畫效果
一. 改變約束值實現動畫
將 blueView 的寬度拉成屬性 BlueView_Width, 改變 BlueView_Width 的 constant 值, 然後在UIView.animate 中新增 strongSelf.view.layoutIfNeeded(), 更新controller View 的子檢視佈局, 不新增的 strongSelf.view.layoutIfNeeded() 沒有動畫效果
blueView 是 View 的子檢視, blueView 的寬度改變時, view 的 viewWillLayoutSubviews 會執行
@IBOutlet weak var blueView: UIView! @IBOutlet weak var greenView: UIView! @IBOutlet weak var BlueView_Width: NSLayoutConstraint! let blueWidth = BlueView_Width.constant + 10 BlueView_Width.constant = blueWidth UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.8, options: .curveEaseIn, animations: { [weak self] in if let strongSelf = self { strongSelf.view.layoutIfNeeded() } }, completion: nil)
二.使用 frame 實現動畫
view 的 viewWillLayoutSubviews 不會執行
錯誤:
blueView 的寬度改變了, 但是 greenView 的寬度沒有隨著改變
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.8, options: .curveEaseIn, animations: { [weak self] in if let strongSelf = self { let blueWidth = strongSelf.blueView.frame.width + 10 strongSelf.blueView.frame.size.width = blueWidth strongSelf.view.layoutIfNeeded() } }, completion: nil)
因為 blueView 和 greenView 的約束是通過 Autolayout 建立的, 所以改變 blueView frame 時, 它的子檢視並不會隨之改變, view 的 viewWillLayoutSubviews 不會執行, 要讓 greenView 寬度改變, 需要改變 greenView 的 frame
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.8, options: .curveEaseIn, animations: { [weak self] in
if let strongSelf = self {
let blueWidth = strongSelf.blueView.frame.width + 10
strongSelf.blueView.frame.size.width = blueWidth
strongSelf.greenView.frame.size.width = 70
strongSelf.view.layoutIfNeeded()
}
}, completion: nil)
如果使用 blueView 的 layoutIfNeeded() 方法, 需要寫在改變 greenView 寬度之前, 寫在之後沒有效果
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.8, options: .curveEaseIn, animations: { [weak self] in
if let strongSelf = self {
let blueWidth = strongSelf.blueView.frame.width + 10
strongSelf.blueView.frame.size.width = blueWidth
strongSelf.blueView.layoutSubviews()
strongSelf.greenView.frame.size.width = 70
}
}, completion: nil)