✅ 이번 시간에는 ch11에서 애니메이션을 중점으로 하여 코드리뷰를 진행할 생각이야.
이 페이지를 보기 전! 자세한 이해를 위해 [개념편]을 참고하기 바래
2021.06.22 - [iOS/패캠공부] - 💈 ch11 Animation - 개념편💈
개념 편에서 언급했듯이
1. 제약조건을 통해 애니메이션을 구현하거나,
2. 뷰를 통해 constraint를 조작하거나 두가지 방법이 있어.
1️⃣ 제약조건을 통해 애니메이션을 구현하는 방법
제약조건도 버튼이나 레이블 등과 마찬가지로 IBOulet을 연결할 수 있는데 이를 이용해서 직접 컨트롤이 가능해.
✅ 애니메이션이 정상적으로 작동하려면 사전 준비가 필요해.
1. 메모리에 뷰가 올라왔을 때,
2. 뷰가 화면에 보여질 때, (주석의 표현이 조금 모호해)
- 여기서 주의할 점은 viewWillAppear을 사용하면, 뷰가 올라오기 전에 코드가 실행해서 내가 원하는 바와 다른 결과를 얻을 수 있어.
✅ 자 그럼 사전 준비가 끝났다면 메모리에 올라왔을 때, 어떤 액션을 취하는지 코드로 한번 볼까?
private func prepareAnimation() {
nameLabelCenterX.constant = view.bounds.width // 확실하게 뷰의 바깥으로 내보내기 위해서
bountyLabelCenterX.constant = view.bounds.width // 확실하게 뷰의 바깥으로 내보내기 위해서
}
바깥에서 짜라란~ 하고 등장하는 코드라서 이런 액션을 취하게 돼.
코드에 대해서 분석해보면, 아까 연결했던 네임레이블과 바운티레이블의 제약조건을 뷰의 끝점에 위치하게 해.
어떤 말이냐면 저런 식으로 작성하게 되면, 뷰의 width의 크기 지점에 label의 시작지점이 잡히게 되서 아예 글자가 바깥으로 나가버리는 효과가 있어.
✅ 그럼 메모리에 올라오고 난 후, 이제는 화면에 보여질때 어떤 액션을 취하는지 볼까?
private func showAnimation() {
nameLabelCenterX.constant = 0
bountyLabelCenterX.constant = 0
/* 가장 간략한
UIView.animate(withDuration: 0.3) { // 0.3초동안
self.view.layoutIfNeeded() // 레이아웃을 다시 해야할 필요가 있다면 다시 해라
}*/
/* 조금 더 스탠다드한
UIView.animate(withDuration: 0.3,
delay: 0.1,
options: .curveEaseIn,
animations : {
self.view.layoutIfNeeded()
}, completion: nil)
*/
// 글자가 스프링처럼 튕기는 코드
UIView.animate(withDuration: 0.5, delay: 0.2, usingSpringWithDamping: 0.6, initialSpringVelocity: 2, options: .allowUserInteraction, animations: self.view.layoutIfNeeded, completion: nil)
// 카드가 돌아감
UIView.transition(with: imgView, duration: 0.3, options: .transitionFlipFromLeft, animations: nil, completion: nil)
}
주목할만한 점으로는 각 레이블 제약조건을 constant = 0로 바꾼다는 점이야.
이게 어떤 의미이냐면, 기존에 설정되어 있는 제약조건으로 돌려놓는 다는 말이야
- self.view.layoutIfNeeded() : 레이아웃을 조정할 필요가 있으면 조정해라.
나머지 코드는 그냥 딱 보면 이해가 갈거니까 응용해 보기 바라.
https://github.com/lgvv/fastCampus/tree/main/BountyList%20-%20Collection%2BAnimate
----------------------------------------------------------------------------------------------------------------------
✅ 여기부턴 뷰의 속성을 이용하여 애니메이트!
여기도 위와 마찬가지로 viewDidLoad와 viewDidAppear 부분을 똑같아.
하.지.만!!
✅ 메모리에 올라왔을때 조금은 다르게 코딩해야해
private func prepareAnimation() {
nameLabel.transform = CGAffineTransform(translationX: view.bounds.width, y: 0).scaledBy(x: 3, y: 3).rotated(by: 180) // 위치이동 - 스케일은 3배 - 회전은 180도
bountyLabel.transform = CGAffineTransform(translationX: view.bounds.width, y: 0).scaledBy(x: 3, y: 3).rotated(by: 180) // 위치이동 - 스케일은 3배 - 회전은 180도
nameLabel.alpha = 0
bountyLabel.alpha = 0
}
사전준비 하는 부분이 조금 달라.
개념편에서 보았다 싶이 transform을 이용할거야.
CGAffineTransform을 이용해서
translation(이동)을 활용해서 위치를 y축은 그대로 두고 x축을 변경해서 화면 밖으로 내보내
scaledBy(확대)를 이용해서 x와y 값을 3배 크게 만든 후에
rotated(회전)을 이용해서 180도 회전을 만들어.
그 다음에 alpha 값을 주어서 투명하게 만드는게 초기 작업이야.
✅ 그럼 이제 화면에 나타나기 전에 어떠한 액션을 취하는지 볼까?
private func showAnimation() {
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 2, options: .allowUserInteraction, animations: {
self.nameLabel.transform = CGAffineTransform.identity // 변형이 없는 모습의 정보로
self.nameLabel.alpha = 1
}, completion: nil)
UIView.animate(withDuration: 1, delay: 0.2, usingSpringWithDamping: 0.6, initialSpringVelocity: 2, options: .allowUserInteraction, animations: {
self.bountyLabel.transform = CGAffineTransform.identity
self.bountyLabel.alpha = 1
}, completion: nil)
UIView.transition(with: imgView, duration: 0.3, options: .transitionFlipFromLeft, animations: nil, completion: nil)
}
UIView API를 이용하여 애니메이션을 줄건데 파라미터는 읽어보면 쉽게 파악할 수 있을거야.
몇가지 주목할만한 점은
1. 애니메이트를 분리해서 각각의 레이블에 다른 효과를 주어서 더 완성도 있게 만들었다.
2. CGAffineTransform.identity : 처음에 변형이 없는 모습의 정보로
https://github.com/lgvv/fastCampus/tree/main/BountyList%20-%20Collection%20%2B%20Animate2
참고
'Archive > 패캠(올인원)' 카테고리의 다른 글
🦧 ch13 Static Cell (TableView) (0) | 2021.06.25 |
---|---|
ch12 애플뮤직st 음악앱 코드리뷰 (0) | 2021.06.24 |
ch11 현상금 랭킹앱 코드리뷰(CollectionView) (0) | 2021.06.22 |
💈 ch11 Animation - 개념편💈 (0) | 2021.06.22 |
ch10 현상금 랭킹앱 코드리뷰(MVVM) (0) | 2021.06.21 |