1 Animation
- 좀더 부드러운 모션과 사용자의 몰입도를 높이기 위해 view에 다양한 애니메이션을 넣어보자.
- 이전에 만들었던 원피스 현상금 앱의 Detail View Controller의 레이블에 애니메이션을 넣을 것이다.
- 각 레이블이 우측 화면 밖에서 화면의 중심축으로 날아오도록 애니메이션을 구현할 것이다.
- 가장 먼저 레이블에 center horizontally constraint를 적용한다.
- 적용한 constraint 클릭 -> control누른채로 오른쪽 코드 화면으로 드래그
- 두 레이블의 constraint에서 outlet을 연결하였다.
- 작업을 마치기 전에 화면에 잘 나오도록 각 레이블과 이미지뷰에 constraints를 넣어서 마무리 하자.
2 코드작성
import UIKit
class DetailViewController: UIViewController {
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var bountyLabel: UILabel!
@IBOutlet weak var nameLabelCenterX: NSLayoutConstraint!
@IBOutlet weak var bountyLabelCenterX: NSLayoutConstraint!
let viewModel = DetailViewModel()
// viewDidLoad()는 메모리에 올라오는 순간에 수행되는 함수이다
// 메모리에 올라오자마자 prepareAnimation으로 애니메이션 준비를 위한 동작을 수행하도록 하자.
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
prepareAnimation()
}
// viewDidAppear는 view가 화면에 나타나는 순간 동작한다.
// 여기서 showAnimation으로 애니메이션을 보여주자
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
showAnimation()
}
*prepareAnimation()
- constant를 먼저 알고 넘어가야 하는데 nameLabel의 constraint를 클릭하고 attributes inspector를 보자.
- name label은 화면의 x축 중심에 놓이도록 constraint가 적용되어있다. 여기서 constant는 이 x축에 대한 좌표가 된다.
- 0은 중심, 400이면 오른쪽으로 400, -300이면 왼쪽으로 300 위치에 레이블이 있게 된다.
- 레이블이 우측에서 0(중심)위치로 날아오도록 애니메이션을 넣을 것이기 때문에 prepareAnimation단계에서 constant를 화면 밖 좌표로 설정해줘야 한다.
- view.bounds를 활용해서 화면 밖으로 constant를 초기화 해주자.
private func prepareAnimation() {
nameLabelCenterX.constant = view.bounds.width
bountyLabelCenterX.constant = view.bounds.width
}
*showAnimation()
- 이제 화면에 view가 나타났을때 애니메이션을 보여주는 동작을 구현해보자.
- 다시 각 레이블의 constant를 0으로 바꿔준다.
private func showAnimation() {
nameLabelCenterX.constant = 0
bountyLabelCenterX.constant = 0
UIView.animate(
withDuration: 0.3,
delay: 0,
options: .curveEaseIn,
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
}
- duration은 애니메이션의 지속시간이다.
- delay로 애니메이션 시작을 늦출 수 있다.
- options으로는 다양한 애니메이션 효과를 적용할 수 있다. curveEaseIn은 천천히 날아오다가 빨라지는 효과이다.
- constant에 새로운 값을 넣어주었기 때문에 레이아웃이 변경될 수 있다. 필요하다면 다시 layout을 잡아주는 역할을 layoutIfNeeded가 수행한다.
- view의 애니메이션이 auto layout을 벗어나면 다시 layout을 잡아줘야 하기 때문에 위 작업이 필요하다.
- completion은 애니메이션이 완료되고 나서 수행할 동작을 추가하는 곳이다.
UIView.animate(
withDuration: 0.5,
delay: 0.2,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 2,
options: .allowUserInteraction,
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
- 이번에는 다른 애니메이션을 살펴보자. 이렇게 하면 레이블이 스프링처럼 튕기는 모션도 넣을 수 있다.
3 전체코드
import UIKit
class DetailViewController: UIViewController {
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var bountyLabel: UILabel!
@IBOutlet weak var nameLabelCenterX: NSLayoutConstraint!
@IBOutlet weak var bountyLabelCenterX: NSLayoutConstraint!
let viewModel = DetailViewModel()
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
prepareAnimation()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
showAnimation()
}
private func prepareAnimation() {
nameLabelCenterX.constant = view.bounds.width
bountyLabelCenterX.constant = view.bounds.width
}
private func showAnimation() {
nameLabelCenterX.constant = 0
bountyLabelCenterX.constant = 0
UIView.animate(
withDuration: 0.3,
delay: 0,
options: .curveEaseIn,
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
}
func updateUI() {
if let bountyInfo = viewModel.bountyInfo {
imgView.image = bountyInfo.image
nameLabel.text = bountyInfo.name
bountyLabel.text = "\(bountyInfo.bounty)"
}
}
@IBAction func close(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
4 동작 화면
- 레이블이 오른쪽에서 날아오는 것을 볼 수 있다.
'ComputerScience > ios App(Storyboard)' 카테고리의 다른 글
ios - 18 Animation with ViewProperties (0) | 2021.08.03 |
---|---|
ios - 16 CollectionView (0) | 2021.08.03 |
ios - 15 Design Pattern (0) | 2021.08.02 |
ios - 14 Segue (0) | 2021.07.28 |
ios - 13 Custom Cell (0) | 2021.07.28 |