Save 37% off PRO during our Black Friday Sale! »

Swipe Transition

Swipe Transition

0620564f0125b8b3b7f4fe40c10b8b4e?s=128

Tatsuya Tanaka

January 24, 2018
Tweet

Transcript

  1. Swipe Transition #potatotips 47 ాத ୡ໵ (@tattn)

  2. • Yahoo!৐׵Ҋ಺ • iOSΞϓϦΤϯδχΞ • GitHub: @tattn • Qiita: @tattn

    • Twitter: @tanakasan2525 ాத ୡ໵ (@tattn)
  3. Α͋͘Δ
 ศརͳεϫΠϓδΣενϟʔ Λ࣮૷ͯ͠Έ·ͨ͠

  4. ͲͷҐஔͰ΋ εϫΠϓόοΫͰ͖Δ

  5.  ը໘ͷͲ͜Ͱ΋ࠨʹεϫΠϓͰ͖Δ ը໘୺(Τοδ)Ͱͳͯ͘΋OK

  6.  Sloppy Swiping ͱ΋ݺ͹Ε͍ͯ·͢ɻ ͜ͷεϥΠυͰ͸γϯϓϧʹ
 SwipeBackͱදه͠·͢ɻ

  7. ԼεϫΠϓͰϞʔμϧΛด͡Δ

  8.  ԼʹεϫΠϓ͢ΔͱϞʔμϧͷը໘͕εϫΠϓͱͱ΋ʹҠಈ͠ɺ
 ͋Δఔ౓εΫϩʔϧ͢Δͱด͡Δ

  9.  ͜ͷεϥΠυͰ͸
 SwipeToDismissͱදه͠·͢ɻ

  10.  ࣮૷ͯ͠Έ·ͨ͠ͷͰɺ
 ͦͷ࣮૷ํ๏Λ͝঺հ͠·͢

  11. ࣮૷ํ๏

  12. ࠓճͷओͳొ৔ਓ෺  • UIPanGestureRecognizer • UIViewControllerAnimatedTransitioning • UIViewControllerTransitioningDelegate • UINavigationControllerDelegate

    • UIPercentDrivenInteractiveTransition
  13. UIPanGestureRecognizer ࢦͷҠಈྔͳͲΛऔಘͰ͖ΔΫϥεɻ ࠓճ͸͜ΕͰεϫΠϓΛݕग़͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJQBOHFTUVSFSFDPHOJ[FS

  14. UIViewControllerAnimatedTransitioning ࣗ࡞ͷը໘ભҠΛ࣮૷Ͱ͖Δϓϩτίϧɻ SwipeBackͰ͸ViewΛӈʹҠಈɺ
 SwipeToDismissͰ͸ViewΛԼʹҠಈ
 ͢ΔͨΊʹ࢖༻͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJWJFXDPOUSPMMFSBOJNBUFEUSBOTJUJPOJOH

  15. UIViewControllerTransitioningDelegate present/dismiss࣌ʹ
 Ͳͷτϥϯδγϣϯ(UIViewControllerAnimatedTransitioning)Λ
 ར༻͢Δͷ͔Λࢦఆ͢Δϓϩτίϧɻ 
 SwipeToDismissͰࣗ࡞ͷը໘ભҠΛར༻͢ΔͨΊʹ
 ࢖༻͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJWJFXDPOUSPMMFSUSBOTJUJPOJOHEFMFHBUF

  16. UINavigationControllerDelegate UINavigationControllerͰൃੜ͢ΔΠϕϯτͷัଊ΍
 Ͳͷτϥϯδγϣϯ(UIViewControllerAnimatedTransitioning)Λ
 ར༻͢Δͷ͔Λࢦఆ͢Δϓϩτίϧɻ 
 SwipeBackͰࣗ࡞ͷը໘ભҠΛར༻͢ΔͨΊʹ
 ࢖༻͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJOBWJHBUJPODPOUSPMMFSEFMFHBUF

  17. UIPercentDrivenInteractiveTransition ը໘ભҠͷิؒํ๏ͷࢦఆ΍
 ը໘ભҠ͕Կ%׬͍ྃͯ͠Δͷ͔ͳͲΛ
 ઃఆ͢ΔΫϥεɻ
 
 SwipeBackͱSwipeToDismissͰ
 Ͳ͜·ͰεϫΠϓͨ͠ͷ͔Λදݱ͢ΔͨΊʹ࢖༻͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJQFSDFOUESJWFOJOUFSBDUJWFUSBOTJUJPO

  18. (ൃද࣌ؒͷؔ܎Ͱ)
 SwipeBackͷํΛ঺հ͠·͢ɻ (SwipeToDismiss΋΄΅ಉ࣮͡૷Ͱग़དྷ·͢ɻ)

  19. SwipeBackAnimator  class SwipeBackAnimator: NSObject, UIViewControllerAnimatedTransitioning { func animateTransition(using transitionContext:

    UIViewControllerContextTransitioning) { guard let to = transitionContext.viewController(forKey: .to), let from = transitionContext.viewController(forKey: .from) else { return } let containerView = transitionContext.containerView containerView.insertSubview(to.view, belowSubview: from.view) to.view.frame = containerView.frame ભҠݩͷviewͷԼʹભҠޙͷviewΛinsert͍ͯ͠·͢ɻ
 SwipeBack࣌ʹԼͷViewΛදࣔ͢ΔͨΊͰ͢ɻ
  20.  ͜ͷ෦෼

  21. SwipeBackAnimator  // ύϥϥοΫεޮՌ to.view.transform.tx = -containerView.bounds.width * 0.3 UIView.animate(

    withDuration: transitionDuration(using: transitionContext), delay: 0, options: .curveLinear, animations: { to.view.transform = .identity from.view.transform = CGAffineTransform(translationX: to.view.frame.width, y: 0) }, completion: { _ in from.view.transform = .identity transitionContext.completeTransition( !transitionContext.transitionWasCancelled ) }) ભҠޙͷviewʹύϥϥοΫεޮՌΛ෇͚ͭͭɺ
 ભҠલͷviewΛӈ΁Ҡಈ
  22. SwipeBackNavigationController  class SwipeBackNavigationController: UINavigationController { private let animator =

    SwipeBackAnimator() private var interactiveTransition: UIPercentDrivenInteractiveTransition! override func viewDidLoad() { super.viewDidLoad() delegate = self let panGesture = UIPanGestureRecognizer() panGesture.addTarget(self, action: #selector(handlePanGesture(_:))) panGesture.maximumNumberOfTouches = 1 view.addGestureRecognizer(panGesture) } viewʹUIPanGestureRecognizerͱ
 UINavigationControllerDelegateΛηοτ
  23. SwipeBackNavigationController  extension SwipeBackNavigationController: UINavigationControllerDelegate { public func navigationController(_ navigationController:

    UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { return operation == .pop ? animator : nil } public func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { return interactiveTransition } } ར༻͢Δࣗ࡞ͷτϥϯδγϣϯΛฦ͢ɻ (εϥΠυʹࡌͤΔͱਏ͍ݟͨ໨Ͱ͕͢ɺ࣮૷͍ͯ͠Δͷ͸2ߦͰ͢)
  24. SwipeBackNavigationController  @objc private func handlePanGesture(_ recognizer: UIPanGestureRecognizer) { switch

    recognizer.state { case .began: interactiveTransition = UIPercentDrivenInteractiveTransition() interactiveTransition.completionCurve = .linear popViewController(animated: true) case .changed: let translation = recognizer.translation(in: view) interactiveTransition.update(translation.x / view.bounds.width) case .ended: if recognizer.velocity(in: view).x > 0 { interactiveTransition.finish() interactiveTransition = nil } else { fallthrough } case .cancelled: interactiveTransition.cancel() interactiveTransition = nil default: break } } δΣενϟʔʹ߹Θͤͯঢ়ଶΛߋ৽
  25. ׬੒ 100ߦຬͨͳ͍ίʔυͰ
 γϯϓϧͳSwipeBackΛ࣮૷Ͱ͖·ͨ͠ɻ ࠓճͷ࣮૷͸ˣʹஔ͍ͯ͋Γ·͢ɻ https://github.com/tattn/SwipeTransitionExample

  26. ϥΠϒϥϦԽ

  27. ͔ͤͬ͘ͳͷͰϥΠϒϥϦԽ͠·ͨ͠ https://github.com/tattn/SwipeTransition ScrollView͕͋ͬͯ΋ಈ࡞͢ΔΑ͏ʹͨ͠Γɺ
 Method SwizzlingͰશը໘ʹద༻͢Δػೳ΋͋Γ·͢ɻ SwipeTransition ͥͻɺ͓ࢼ͍ͩ͘͠͞ʂ

  28. ·ͱΊ

  29. ·ͱΊ ʘδΣενϟʔͰૉఢUXΛ໨ࢦͦ͏ʗ
 ʘʘ\\٩( 'ω' )و //ʗʗ ఏڙ͞Ε͍ͯΔ࢓૊ΈΛར༻͢Δ͜ͱͰ
 ҙ֎ͱ؆୯ʹ࣮૷͢Δ͜ͱ͕ग़དྷ·ͨ͠