본문 바로가기

iOS

iOS 사용성 최대로 올려보자! (Part4) - UIViewController Non Interactive Transition

저번 포스팅에서는 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

 

HeroTransitions/Hero

Elegant transition library for iOS & tvOS. Contribute to HeroTransitions/Hero development by creating an account on GitHub.

github.com

 

그러나 아래의 raraywenderlich 예제를  Hero를 사용하면 어떨까요? 

오히려 직접 구현하는 것이 더 편할 수 있을 겁입니다.

 

 

 


 

UIViewController도 UIView와 마찬가지로 

1. Non Interactive Animation

2. Interactive Animation

 

두 가지를 지원하고 있습니다.

 

Interactive Animator 는 이번 주제에서 다루지 않습니다.

 

UIKit 은 Animator object를 query하고 사용자 전환 Animation을 제공합니다.

UIViewControllerTransitioningDelegate 에 객체에 대해 조금 더 살펴보시면 이해를 하실 수 있을 것 입니다.

UIViewControllerTransitioningDelegate

TransitionDelegate는 사용자가 정의하고 UIViewControllerTransitioningDelegate 프로토콜을 따르는 객체입니다.

https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/Art/VCPG_custom-presentation-and-animator-objects_10-1_2x.png

 

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입니다.

 

The from and to objects

 

 

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()
    }
}

 

UITabBarControllerDelegate

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

 

kimtaesu/UITransition

Contribute to kimtaesu/UITransition development by creating an account on GitHub.

github.com

 

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를 다 읽으시고 경험하신다면 좋은 앱 개발자가 될 것입니다.

 

SourceCode

 

소중한 시간 내어서 읽어주셔서 감사합니다