2020/05/15 - [iOS] - [iOS] 화면전환 애니메이션 커스텀하기 - CGAffineTransform, animateTransition [1]
에서 도움을 얻었습니다!
다음과 같은 트랜지션 애니메이션을 만들어 낼 것입니다!
이번 시간에는, 저번 1편에서 배운 CGAffineTransform()을 이용해서 NavigationController Transition을 만들어 볼 것입니다! 꽤 험난한데, 일단 천천히 가보겠습니다. 사용할 중요한 구조는 두가지입니다.
1. 구조 알아보기
Transition의 구조를 먼저 파악해 보겠습니다!
1. 위는 UIViewControllerTransitioningDelegate 내에서 발생하는 일입니다.
UIKit은 animationController(forPresented:presenting:source:)를 호출합니다.
이 친구는 UIViewControllerAnimatedTransitioning 객체를 리턴하는데요, 이 값을 변경해주어야 합니다.
디폴트는 nil입니다. 만약 nil을 리턴받으면 객체는 기본 트랜지션 애니메이션을 가지게 됩니다.
다른 UIViewControllerAnimatedTransitioning 객체를 만들어서, 리턴을 받도록 하겠습니다.
2. 애니메이션이 진행중인 동안, animateTransition(..) 이 호출됩니다. 이 animateTransition(..) 에서는 트랜지션이 진행중인 뷰 -
즉 FromVC와 toVC를 모두 관리할 수 있습니다. fade, scale, rotate와 원하는대로의 커스텀을 이곳에서 할 수 있습니다.
두가지를 알아보았는데요, 이를 매개할 딜리게이트를 잠시 알아보면....
바로 얘입니다. 아까 파란색 걔. UIViewControllerAnimatedTransitioning.
Animate를 관장할 Swift파일을 만들어 줄 것입니다. 그리고 이 파란색 친구를 상속시킵니다.
2. 코드 작성하기
천천히 해보겠습니다. 예제의 경우, PopAnimator.swift입니다.
class PopAnimator: NSObject, UIViewControllerAnimatedTransitioning {
}
다음과 같이 선언을 해 주면, 필수적으로 오버라이딩해야 하는 함수 두개가 호출됩니다.
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
}
1 : 이름에서 알 수 있듯, transitionDuration은 뷰가 전환될 때의 Duration입니다. Duration은 미리 상수로 선언해서 0.8입니다.
2 : 아까 노란색 걔입니다. animatedTransition. 여기 안에서 애니메이션을 만들것입니다.
1) HomeViewController (FromVC)
HomeVC와 DetailVC는 Segue로 연결되어 있습니다.
구조는 위와 같습니다. 예상하건데,
Segue는 prepare(for:sender:)를 타고 움직이므로, prepare(for:sender:) 내에 delegate를 선언할 것입니다.
HomeVC에서 Transition을 관장하는 delegate를 채택해 보겠습니다!
extension HomeViewController: UIViewControllerTransitioningDelegate {
}
UIViewControllerTransitioningDelegate를 선언해주고, 이 안에서 아까 맨 위에서 설명한 animationController(forPresented:presenting:source:) 함수를 선언할 것입니다.. 너무 어렵죠... 제가 봐도 그런데요...ㅠㅠ
홧팅. 다음은 본격적인 애니메이션 만들기입니다!
3. Animator 이용
let transition = PopAnimator()
와 같이 선언합니다. HomeVC입니다.
그다음, Transition이 Custom임을 나타낸다고 했었던 파란색 걔 UIViewControllerAnimatedTransitioning 입니다. 얘를 PopAnimator로 지정해 줄 것입니다.
func animationController(
forPresented presented: UIViewController,
presenting: UIViewController, source: UIViewController)
-> UIViewControllerAnimatedTransitioning? {
return transition
}
위는 forPresented, 아래는 forDismissed에 해당하는 트랜지션입니다. 두개를 다르게 선언해 줍니다.
func animationController(forDismissed dismissed: UIViewController)
-> UIViewControllerAnimatedTransitioning? {
return nil
}
이대로 실행해도 실행은 잘 되는데요, 트랜지션 효과를 넣지 않았으니 별로 예쁜 모양은 나오지 않습니다.
실행을 위해 애니메이션을 추가해 볼게요.
let containerView = transitionContext.containerView
let toView = transitionContext.view(forKey: .to)!
let recipeView = presenting ? toView : transitionContext.view(forKey: .from)!
fromVC와 toVC를 선언했습니다. 아래 두줄은 어렵지 않습니다. 이전 뷰에서 다음 뷰를 key로 받아왔습니다.
presenting은 Bool으로, 트랜지션이 진행중이면 true, 아닌 경우 false입니다.
첫 줄의 containerView는 Transition에 관련한 View들의 SuperView입니다.
위 사진으로 이해하면 잘 이해할 수 있습니다.
필요한 세개의 구성성분을 잘 선언했으니 사용해야 합니다.
Old View는 새로운 뷰가 나타남에 따라 사라지는 효과를 만들어 낼 것입니다.
아래는 animateTransition(using:):.에 선언해 줍니다.
containerView.addSubview(toView)
toView.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
UIView.animate(
withDuration: duration,
animations: {
toView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
},
completion: { _ in
transitionContext.completeTransition(true)
}
)
CGAffineTransform(scaleX: ~ , y: ~)
입니다. 위는 저번 시간 포스팅에 잘 나와 있는데요, 원래 뷰의 크기를 대입된 가로(X) 나 세로(y)로 늘리거나 줄이는 방식입니다.
'iOS' 카테고리의 다른 글
[iOS] UIDynamicAnimatior, UICollisionBehavior, UIGravityBehavior (2) | 2020.06.13 |
---|---|
[iOS] 앱 내 기본글꼴 커스텀 폰트로 설정하기 (0) | 2020.05.30 |
[iOS] 화면전환 애니메이션 커스텀하기 - CGAffineTransform, animateTransition [1] (3) | 2020.05.15 |
[iOS] SideBar (3) | 2020.05.09 |
[iOS] Calendar (2) (0) | 2020.05.02 |