저번 포스팅에서는 Interactive Animation 를 다루는 방법을 살펴보았습니다.
이 포스팅은 "사용성 최대로 올려보자!"의 Series 중 일부입니다.
1. iOS 사용성 최대로 올려보자! (Part1) - PaintCode
2. iOS 사용성 최대로 올려보자! (Part2) - ShapeShifter
3. iOS 사용성 최대로 올려보자! (Part3) - UIView Interactive Animation
4. iOS 사용성 최대로 올려보자! (Part4) - UIViewController Non Interactive Transition
5. iOS 사용성 최대로 올려보자! (Part5) - Easing function
6. iOS 사용성 최대로 올려보자! (Final) - UIViewController Interactive Transition
ViewController 의 Transtion 사용하기 위해 Hero를 선택한 것은 정말 멋진 일입니다.
기본적으로 정말 다양한 Animation을 지원하고 있기 때문입니다.
https://github.com/HeroTransitions/Hero
그러나 아래의 raraywenderlich 예제를 Hero를 사용하면 어떨까요?
오히려 직접 구현하는 것이 더 편할 수 있을 겁입니다.
UIViewController도 UIView와 마찬가지로
1. Non Interactive Animation
2. Interactive Animation
두 가지를 지원하고 있습니다.
Interactive Animator 는 이번 주제에서 다루지 않습니다.
UIKit 은 Animator object를 query하고 사용자 전환 Animation을 제공합니다.
UIViewControllerTransitioningDelegate 에 객체에 대해 조금 더 살펴보시면 이해를 하실 수 있을 것 입니다.
UIViewControllerTransitioningDelegate
TransitionDelegate는 사용자가 정의하고 UIViewControllerTransitioningDelegate 프로토콜을 따르는 객체입니다.
Animator objects:
Animator objects는 ViewController의 View를 표시하거나 숨기는 데 사용되는 애니메이션을 만드는 역할을 합니다.
ViewController 표시하고 해제하기 위해 별도의 애니메이터 객체를 제공 할 수 있습니다
Animator objects는 `UIViewControllerAnimatedTransitioning` 프로토콜을 따릅니다.
Interactive animator objects:
touch events, gesture recognizers를 사용하여 사용자 정의 애니메이션의 타이밍을 구동합니다.
Interactive animator objects는 `UIViewControllerInteractiveTransitioning` 프로토콜을 따릅니다.
Presentation controller:
PresentationController는 ViewController가 화면에 있는 동안 Presentation Style 을 관리합니다.
자신의 Presentation Style에 맞는 맞춤형 PresentationController를 제공 할 수 있습니다.
CustomPresentations를 만드는 방법을 참조하세요.
ViewController의 Presentation Style을 UIModalPresentationCustom으로 설정하고 Transition Delegate를 제공하면
UIKit은 사용자 지정 Presentation Controller를 대신 사용합니다.
`present` or `dismiss` transitioningDelegate 시퀀스 다이어그램
The Transitioning Context Object
UIViewControllerContextTransitioning 프로토콜을 구현하고 Transition과 관련된 ViewContoller 및 View에 대한 참조를 저장합니다.
또한 애니메이션이 Interactive인지 여부를 포함하여 Transition을 수행하는 방법에 대한 정보도 저장합니다.
Transition의 자세한 정보는 UIViewControllerContextTransitioning Protocol Reference 를 확인해 주세요.
Transition Context Object 는 to, from의 ViewController를 가져 올 수 있습니다.
to: Transition이 끝날 때 View가 표시되는 ViewController입니다.
from: Transition이 시작하는 View가 표시되는 ViewController입니다.
Hero 는 아래와 같이 3개의 TransitionDelgate protocol을 따르고 있습니다.
우리가 진행하는 예제도 마찬가지로 3개의 Transition Delegate protocol을 따르고
사용자 정의 Transition을 지정할 수 있습니다.
UIViewContollerTransitionDelegate
extension CustomViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CustomPresentSlideAnimatedTransitioning()
}
}
UINavigateionControllerDelegate
extension CustomViewController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CustomPresentSlideAnimatedTransitioning()
}
}
extension CustomTabbarViewController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CustomPresentSlideAnimatedTransitioning()
}
}
SlideInAnimator 코드입니다.
https://github.com/kimtaesu/UITransition/blob/master/UITransition/Custom/SlideInAnimator.swift
Demo
위에 transitioningDelegate 순서대로 이해해보도록 하겠습니다.
1. UIKit이 animationControllerForPresentedController:presentingController:sourceController: 을 호출하면 CustomPresentSlideAnimatedTransitioning을 반환합니다.
2. UIKit은 ViewController가 사용자 정의 Interactive animator object가 있는지 Query 합니다.
3. interactive animator를 nil 로 return 합니다.
4. UIKit User Interaction 없는 Animation으로 진행합니다.
5. UIKit은 CustomPresentSlideAnimatedTransitioning 의 transitionDuration:using 를 호출하면 1을 반환합니다.
6. UIKit은 CustomPresentSlideAnimatedTransitioning 의 animateTransition:using 를 호출하면 animation 을 지정합니다.
7. Transition Context Object 의 from, to 로 시작 - 끝의 ViewController를 가져옵니다.
8. from의 snapshotView을 생성합니다.
SnapshotView
현재 뷰의 내용을 기반으로 스냅 샷 뷰를 반환합니다.
뷰의 현재 렌더링 된 모양을 매우 효율적으로 캡처하고이를 사용하여 새 스냅 샷 뷰를 작성합니다.
큰 뷰 계층을 업데이트하는 데 비용이 많이 드는 애니메이션에 스냅 샷 뷰를 사용하는 것이 효율적입니다.
9. containerView 에 snapshotView, to ViewController를 넣어줍니다.
containerView
컨테이너 뷰는 애니메이션 시퀀스 동안 다른 모든 뷰 (프레젠테이션 및 제시된 뷰 컨트롤러의 뷰를 포함하여)의 슈퍼 뷰 역할을합니다
10. snapshotView, to ViewController의 위치를 지정합니다.
11. Animation 을 실행합니다.
11. transition이 완료되면 completeTransition 호출하여 UIKit에 Transition이 완료되었음을 알립니다.
12. UIKit은 animationEnded 를 호출합니다.
이로써 Slide Left Out Right In 의 Transition이 완성되었습니다.
마무리
이제 사용성이 좋은 앱을 만들기 위해 세 발자국 걸었습니다.
앞으로 Serise를 다 읽으시고 경험하신다면 좋은 앱 개발자가 될 것입니다.
소중한 시간 내어서 읽어주셔서 감사합니다
'iOS' 카테고리의 다른 글
iOS 사용성 최대로 올려보자! (Part5) - Easing function (1) | 2019.08.19 |
---|---|
iOS 사용성 최대로 올려보자! (Part3) - UIView Interactive Animation (1) | 2019.08.19 |
iOS 사용성 최대로 올려보자! (Part2) - ShapeShifter (0) | 2019.08.18 |
iOS 사용성 최대로 올려보자! (Part1) - PaintCode (1) | 2019.08.18 |
iOS Test Case 개발 방법 With ReactorKit (0) | 2019.03.19 |