관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 3. Hero - UIViewController간의 화면전환 애니메이션 프레임워크 (Hero extension, hero.id를 이용한 애니메이션) 본문

iOS framework

[iOS - swift] 3. Hero - UIViewController간의 화면전환 애니메이션 프레임워크 (Hero extension, hero.id를 이용한 애니메이션)

jake-kim 2022. 2. 25. 23:43

1. Hero - UIViewController간의 화면전환 애니메이션 프레임워크 (개념, UIPenGestureRecognizer)

2. Hero - UIViewController간의 화면전환 애니메이션 프레임워크 (modal)

3. Hero - UIViewController간의 화면전환 애니메이션 프레임워크 (Hero extension, hero.id를 이용한 애니메이션)

4. Hero - UIViewController간의 화면전환 애니메이션 프레임워크 (셀 이동, 뷰 이동 애니메이션 예제)

Hero에서 제공하는 Niavigation 관련 메소드

  • HeroExtension으로 유용한 메소드들을 제공

  • 사용 방법은 hero.으로 접근하여 사용
import UIKit

class VC2: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    self.isHeroEnabled = true
  }
  @IBAction func dismissViewController(_ sender: Any) {
    hero.dismissViewController(completion: nil)
  }
}
  • dismiss나 pop하는 메소드
  func dismissViewController(completion: (() -> Void)? = nil) {
    if let navigationController = base.navigationController, navigationController.viewControllers.first != base {
      navigationController.popViewController(animated: true)
    } else {
      base.dismiss(animated: true, completion: completion)
    }
  }
  • 특정 ViewController로 back
  func unwindToRootViewController() {
    unwindToViewController { $0.presentingViewController == nil }
  }
  • Navigation에서 현재 ViewController를 다른 ViewController로 대체
func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) {
  ...
}

hero.id를 이용한 디테일한 애니메이션

  • hero.id를 이용한 화면전환 애니메이션
    • present: pull(direction: .left)
    • dismiss: slide(direction: .down)
    • 파란색 뷰의 주황색 뷰의 hero.id를 갖게하여, VC가 변경될때 뷰도 이동되도록 수정 설정

  • 첫 번째 VC의 파란색뷰와 두 번째 VC의 주황색뷰의 hero.id를 동일하게 설정
// VC1
override func viewDidLoad() {
  super.viewDidLoad()
  self.title = "첫 번째 VC"
  self.blueView.isHeroEnabled = true // <-
  self.blueView.hero.id = "myAnimationTarget" // <-
}

// VC2
override func viewDidLoad() {
  super.viewDidLoad()
  self.orangeView.isHeroEnabled = true // <-
  self.orangeView.hero.id = "myAnimationTarget" // <-
}
  • present될때는 오른쪽에서 왼쪽으로 VC1을 당겨지도록 하고, dismiss될때는 아래로 slide되며 삭제되도록 설정
// VC2
// in viewDidLoad() 
self.hero.modalAnimationType = .selectBy(presenting: .pull(direction: .left), dismissing: .slide(direction: .down))

주의할 점

  • navigationController를 통해 push, pop할때도 animation 적용하고 싶은 경우, navigationController.isHeroEnabled활성화해야 애니메이션 적용
self.navigationController?.isHeroEnabled = true

* 전체 코드: https://github.com/JK0369/ExHeroNavigation

Comments