How to animate a UIImage constraints in Swift 4
I am making a card app and I need to make an animation so that a card would change its constraints to move to another place. How would I do this for a UIImage.
stackoverflow.com
UIView.animate에서 constraint을 변경
예전에 글을 올린 적이 있지만 UIView.animate 내부에서 constraint의 constant 값을 수정해서 animation을 실행할 시, layoutIfNeeded를 클로저 내부에 꼭 호출을 해야 UI가 업데이트 되면서 애니메이션이 동작한다.
그런데 이 때 constant를 수정하기 전, 즉 애니메이션을 실행하기 전에 layoutIfNeeded를 한 번 호출해서 layout의 상태를 업데이트 시켜놓은 뒤에, animation을 실행하는 것이 권고되는 데, 왜냐하면 layout이 업데이트가 되어있지 않음은 의도치 않은 사이드 이펙트를 만들 수 있기 때문이다.
아래와 같은 코드가 있다고 치자.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var redView: UIView!
@IBOutlet weak var blueView: UIView!
@IBOutlet weak var redViewTopConstraint: NSLayoutConstraint!
@IBOutlet weak var blueViewBottomConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func animation(_ sender: Any) {
// animation과 별개로 blueView의 layout을 수정하길 원한다.
blueViewBottomConstraint.constant = 0
// redView에게만 animation을 적용하길 원한다.
UIView.animate(withDuration: 1.0, delay: 0, options: [], animations: {
self.redViewTopConstraint.constant = 0
self.view.layoutIfNeeded()
}, completion: nil)
}
}
다음과 같은 상태에서 button을 클릭했을 시 redView의 상단으로 완전히 달라붙는 애니메이션을 실행하려고 한다. 근데 보다시피 코드에서 UIView.animate이전에 blueView의 constraint을 수정해서 blueView의 layout을 업데이트를 알리는 dirtyflag가 바뀌어져 있는 상황이다. 이 상황에서 애니메이션을 실행하면 아래와 같이 blueView에도 animation이 적용된다.
updateCycle상 아직 업데이트 되지 않은 layout이 있다면 animate 블록 안에서 layoutIfNeeded를 호출할 때 같이 업데이트 되기 때문에 발생하는 현상이다.
그렇기에 아래와 같이 animate를 호출하기 전에 layoutIfNeeded를 호출해서 layout들을 업데이트해놓고 animate를 호출하는 것이 권고된다.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var redView: UIView!
@IBOutlet weak var blueView: UIView!
@IBOutlet weak var redViewTopConstraint: NSLayoutConstraint!
@IBOutlet weak var blueViewBottomConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func animation(_ sender: Any) {
// animation과 별개로 blueView의 layout을 수정하길 원한다.
blueViewBottomConstraint.constant = 0
view.layoutIfNeeded() //layout을 모두 업데이트 시켜놓는다.
// redView에게만 animation을 적용하길 원한다.
UIView.animate(withDuration: 1.0, delay: 0, options: [], animations: {
self.redViewTopConstraint.constant = 0
self.view.layoutIfNeeded()
}, completion: nil)
}
}
'iOS > 이슈' 카테고리의 다른 글
[iOS Issue] CLLocationManager 사용 시 주의할 점 (0) | 2022.05.30 |
---|---|
[iOS Issue] status bar 클릭 시 scrollView가 top으로 이동하는 현상 (0) | 2022.05.25 |
[iOS Issue] Lottie 리소스 용량 관련 이슈 (1) | 2022.04.16 |
[iOS Issue] iOS15에서 소리만 실행되는 notification은 실행 불가 (0) | 2022.04.09 |
[iOS Issue] Webview에서 URL link가 실행되지 않는 이슈 (0) | 2022.03.28 |
댓글