관리 메뉴

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

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

iOS framework

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

jake-kim 2022. 2. 23. 23:35

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

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

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

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

Hero 프레임워크

  • UIViewController간 트랜지션의 애니메이션을 관리하는 프레임워크

https://github.com/HeroTransitions/Hero

  • UIViewController를 상속받고 있는 UINavigation, UITabBarController도 역시 Hero프레임워크에서 지원하므로 트랜지션에 사용 가능

Hero 알아보기

  • 설치 (아래 예제에서는 cocoapods 이용)
pod 'Hero'
  • isHeroEnabled = true로 설정
import UIKit
import Hero

class ViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    
    self.isHeroEnabled = true // <-
  }
}

Attributes 설정

Attributes는 Hero프레임워크에서 UIView의 extension으로 정의한 값

  • isHeroEnabled = true
    • (위 설명에서 설정한 부분)
  • heroID
  • heroModifiers
    • 트랜지션 애니메이션에는 main과 sub가 있는데, sub로 fade, rotate와 같은 부가적인 애니메이션을 설정해줄때 사용
    • 주의: source와 destination 뷰가 있을 때, source 뷰의 heroModifiers는 무시되고 destination 뷰의 heroModifiers가 적용
// https://lkzhao.gitbooks.io/hero/content/docs/UsageGuide.html
view.heroModifiers = [.fade, .translate(x:0, y:-250), .rotate(x:-1.6), .scale(1.5)]

Interactive Transition

  • interactive transition을 사용하기 위해 해야할 3가지 정의
    1. 시작) Hero에게 transition을 시작한다는 것을 명시
    2. 진행) Hero에게 트랜지션 상황을 계속 업데이트
    3. 종료) Hero에게 end/cancel 명시
// start
gestureRecognizer.state == .began

// progress
Hero.shared.update(progress:) & Hero.shared.apply(modifiers:to:)

// cancel/end
Hero.shared.end() or Hero.shared.cancel()
  • 주요 메소드 4가지
// 1
public func update(progress: Double) 

// 2
public func end(animate: Bool = true)

// 3
public func cancel(animate: Bool = true)

// 4
public func apply(modifiers: [HeroModifier], to view: UIView)

ex) UIPanGestureRecogniger에 Hero 적용시키기

  • ViewControllerPannable 정의
    • 해당 gesture를 적용하고 싶은 ViewController들은 상속해서 사용할 수 있도록 설계
import UIKit
import Hero

class ViewControllerPannable: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    
}
  • isHeroEnabled = true로 활성화
// in viewDidLoad

// 1
self.isHeroEnabled = true
  • panGesture 등록
// in viewDidLoad

let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureAction(_:)))
self.view.addGestureRecognizer(panGestureRecognizer)
  • panGestureAction 정의
// ViewControllerPannable.swift

@objc func panGestureAction(_ panGesture: UIPanGestureRecognizer) {
  self.rightToLeftSwipeBackToDismiss(panGesture)
}

private func rightToLeftSwipeBackToDismiss(_ panGesture: UIPanGestureRecognizer) {

}
  • translation과 prgoressRate 프로퍼티 선언
    • translation: 처음 클릭한 부분으로부터 얼마만큼 좌표가 이동된지 변화량 값
    • progressRate: 전체 width중에 얼마만큼 이동되었는지 비율
// in rightToLeftSwipeBackToDismiss(_:)

let translation = panGesture.translation(in: nil)
let progressRate = -translation.x / view.bounds.width
  • panGesture.state에 따른 hero 애니메이션 설정
    • self.hero.dismissViewController(): 제스처가 시작할 때 hero에 dismiss 작업을 등록
      (이 작업은 아래 update와 finish에 의해 적용)
    • Hero.shared.update, apply: 0~1사이의 값을 주어 위에서 등록한 작업을 비율에 따라 실행
    • Hero.finish, cancel: 위에서 등록한 작업을 완료할 것인지, 취소할 것인지 선언
switch panGesture.state {
case .began:
  // 1
  self.hero.dismissViewController()
case .changed:
  // 2
  Hero.shared.update(progressRate)
  Hero.shared.apply(modifiers: [.translate(x: translation.x)], to: self.view)
  break
default:
  // 3
  if progressRate > 0.3 {
    Hero.shared.finish()
  } else {
    Hero.shared.cancel()
  }
}

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

 

* 참고

https://lkzhao.gitbooks.io/hero/content/docs/InteractiveTransition.html

https://lkzhao.gitbooks.io/hero/content/docs/UsageGuide.html

https://github.com/HeroTransitions/Hero

 

Comments