Upgrade to Pro — share decks privately, control downloads, hide ads and more …

もっとFluidでRedirectableなモーダル表示アニメーション

Kazuya Hirobe
September 13, 2018
440

 もっとFluidでRedirectableなモーダル表示アニメーション

Kazuya Hirobe

September 13, 2018
Tweet

Transcript

  1. Designing Fluid Interfaces
 (WWDC 2018) • Fluid : ྲྀମͷɺͳΊΒ͔ͳ •

    ӳޠ೉͔͚ͬͨ͠Ͳɺࠓ͸ࣈນ͋Δ https://developer.apple.com/videos/play/wwdc2018/803/
  2. A tool feels like an extension of your mind •

    ৺ ମͷԆ௕ͷΑ͏ʹײ͡ΒΕΔಓ۩ • iPhone͸௚઀खͰૢ࡞͢Δ΋ͷ • ͏·͘ಈ͚͹ਓؒͷExtensionͱͳΕΔ • ৮Δͷָ͕͘͠ͳΔ
  3. UIViewControllerAnimatedTransitioning • ç func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { if isForPresented

    { // present presentAnimation(transitionContext) } else { // dissmis dissmisAnimation(transitionContext) } } func dissmisAnimation(_ transitionContext: UIViewControllerContextTransitioning) { let containerView = transitionContext.containerView guard let nav = transitionContext.viewController(forKey: .from) as? UINavigationController, let detailVC:DetailViewController = nav.visibleViewController as? DetailViewController else { fatalError() }
  4. UIViewControllerAnimatedTransitioning • ç let fromImageRect = detailVC.detailImageRect(containerView: containerView, safeAreaInsets: from?.view?.safeAreaInsets

    ?? .zero) let toImageRect = detailVC.parentImageViewRect // imageΛҠಈ͢ΔͨΊͷviewΛ࡞੒ let imageView:UIImageView = UIImageView(frame: fromImageRect) imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true imageView.image = detailVC.parentImage containerView.addSubview(imageView) // ॖখΞχϝʔγϣϯ nav.view.isHidden = true UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, options: [.curveEaseInOut], animations: { () -> Void in imageView.frame = toImageRect }) { (finished) -> Void in nav.view.removeFromSuperview() transitionContext.completeTransition(true) } }
  5. ࢦΛ཭ͨ͠ޙͷΞχϝʔγϣϯ • UIViewControllerTransitionDelegate,
 UIViewControllerAnimatedTransitioningΛ࣮૷ • ։࣌͘ʹtransitionDelegateʹηοτ override func collectionView(_ collectionView:

    UICollectionView, didSelectItemAt indexPath: IndexPath) { : let storyboard = UIStoryboard(name: "Main", bundle: nil) guard let vc = storyboard.instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController else { return } let nav = UINavigationController(rootViewController: vc) nav.isNavigationBarHidden = true nav.modalPresentationStyle = .custom nav.transitioningDelegate = vc.modalTransition self.present(nav, animated: true) }
  6. UIViewControllerAnimatedTransitioningΛ ྲྀ༻͠Α͏ class DetailModalTransition : NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { func

    animateTransition(using transitionContext: UIViewControllerContextTransitioning) { if isForPresented { // present // : } else { // dissmis self.dissmisAnimation( containerView: transitionContext.containerView, from: transitionContext.viewController(forKey: .from), to: transitionContext.viewController(forKey: .to), duration: self.transitionDuration(using: transitionContext), completeTransition: transitionContext.completeTransition) } } func dissmisAnimation(containerView: UIView, from: UIViewController?, to: UIViewController?, duration: TimeInterval, completeTransition: @escaping (_ didComplete: Bool) -> Void) { // ΞχϝʔγϣϯΛॻ͘ } }
  7. extension DetailModalTransition { func dissmisFluidly(viewController:UIViewController?) { guard let parent =

    viewController?.presentingViewController, let child = parent.presentedViewController, let window = parent.view?.window else { return } viewController?.dismiss(animated: false) { // viewDidDisappearͷޙʹݺ͹ΕΔͷͰ஫ҙ let containerView = UIView(frame: window.bounds) containerView.isUserInteractionEnabled = false window.addSubview(containerView) self.dissmisAnimation(containerView: containerView, from: child, to: parent, duration: 0.6, completeTransition: { didComplete in containerView.removeFromSuperview() }) } } } UIViewControllerAnimatedTransitioningΛ ྲྀ༻͠Α͏