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

Introduction to micro interactions for iOS apps

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for kiwi kiwi
September 02, 2018

Introduction to micro interactions for iOS apps

iOSDC 2018 (day3)
「iOSマイクロインタラクション入門」登壇資料
https://fortee.jp/iosdc-japan-2018/proposal/f21bf617-3e9c-4ec0-833c-bc8dbb6965e5

(プロポーザルより)
マイクロインタラクションとは、ユーザーが操作した際に表示される、ちょっとしたアニメーションやフィードバックなどのアクションのことです。
Facebookなどのアプリで積極的に採用されており、自分のアプリにも入れてみたい、という方に向けて、マイクロインタラクションの使いどころや実装例を紹介します。

Avatar for kiwi

kiwi

September 02, 2018
Tweet

More Decks by kiwi

Other Decks in Technology

Transcript

  1. Ϧονͳදݱ͕Ͱ͖Δ ૂ͑ΔޮՌ • ϫΫϫΫײ • ੈք؍ͷදݱ ࢖͍Ͳ͜Ζ • ήʔϜͳͲੈք؍͕ڧ͍ΞϓϦ •

    ΢ΥʔΫεϧʔը໘ 5PLZP %JTOFZ3FTPSU"QQ ΢ΥʔΫεϧʔը໘ ىಈ࣌ͷζʔϜͷಈ͖
  2. ΞχϝʔγϣϯΛ࡞ͬͯΈΔr ΆΑΜͱ͢ΔϘλϯ • ඵ਺ͱΞχϝʔγϣϯऴྃޙͷঢ়ଶʢΫϩʔδϟʣΛࢦఆ͢Δͱɺ ͦͷؒΛࣗಈͰิؒͯ͠Ξχϝʔγϣϯͯ͘͠ΕΔ • ࢦఆͰ͖Δ಺༰͸6*7JFXͷϓϩύςΟ • GSBNF΍CPVOETɺഎܠ৭ɺಁ໌౓ •

    USBOTGPSN ճస ֦େॖখ  %BZ-5!5SBDL# • ஗Εඵ਺΍ΠʔζΠϯΞ΢τɺऴྃޙͷॲཧͷࢦఆ͕Մೳͳ೿ੜܕ΋ • ऴྃॲཧͰผͷΞχϝʔγϣϯΛೖΕΔ͜ͱͰɺ࿈ଓͨ͠Ξχϝʔ γϣϯ͕Մೳ UIView.animate(withDuration:animations:)
  3. ΞχϝʔγϣϯΛ࡞ͬͯΈΔr ΆΑΜͱ͢ΔϘλϯ UIView.animate(withDuration:animations:) imageView.bounds.size = CGSize(width: 36, height: 36) UIView.animate(

    withDuration: 0.3, // 秒数 delay: 0, // 0秒後に開始 options: .curveEaseIn, // オプション(カーブ, リピート等) animations: { self.imageView.bounds.size = CGSize(width: 44, height: 44) }, completion: nil)
  4. ΞχϝʔγϣϯΛ࡞ͬͯΈΔr ΆΑΜͱ͢ΔϘλϯ imageView.bounds.size = CGSize(width: 36*0.7, height: 36*0.7) UIView.animate( withDuration:

    0.4, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: .curveEaseInOut, animations: { self.imageView.bounds.size = CGSize(width: 36, height: 36) }, completion: nil)
  5. ΞχϝʔγϣϯΛ࡞ͬͯΈΔr ΆΑΜͱ͢ΔϘλϯ imageView.bounds.size = CGSize(width: 36*0.7, height: 36*0.7) UIView.animate( withDuration:

    0.4, delay: 0.0, usingSpringWithDamping: 0.5, // バネの振幅 initialSpringVelocity: 0.0, // バネの初速 options: .curveEaseInOut, animations: { self.imageView.bounds.size = CGSize(width: 36, height: 36) }, completion: nil)
  6. ΞχϝʔγϣϯΛ࡞ͬͯΈΔ ը໘ભҠ • ը໘ؒͰͲΜͳભҠΛ͢Δ͔Λදͨ͢Ίͷϓϩτίϧ • VTJOHͰ౉͞ΕΔ 6*7JFX$POUSPMMFS$POUFYU5SBOTJUJPOJOHܕͷҾ਺ ͔Βɺલޙͷ7JFX$POUSPMMFS΍7JFX͕औಘՄೳ UIViewControllerAnimatedTransitioning プロトコル

    animateTransition(using:) メソッド func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let containerView = transitionContext.containerView // アニメーション中のcontainer let fromView = transitionContext.view(forKey: .from)! // 今まで表示していたview let toView = transitionContext.view(forKey: .to)! // これから表示するview ...
  7. ΞχϝʔγϣϯΛ࡞ͬͯΈΔ ը໘ભҠ • USBOTJUJPO$POUFYUDPOUBJOFS7JFX͕Ξχϝʔγϣϯͷؒදࣔ͞ΕΔ • ભҠޙͷ7JFX΍Ξχϝʔγϣϯதʹදࣔ͢Δ7JFXΛDPOUBJOFS7JFXʹ BEE4VCWJFX͠ɺΞχϝʔγϣϯͤ͞Δ • ࠓճ͸ɺભҠઐ༻ͷ*NBHF7JFXΛDPOUBJOFSʹ௥Ճ͠ɺ ϦετͷҐஔ͔Βৄࡉը໘ͰͷҐஔ·Ͱಈ͔͢ͱ͍͏ํ਑

    • ৄࡉΛεέϧτϯදࣔ͠ɺͦͷதͰॳظҐஔ͔Βಈ͔͢ํ๏΋͋Δ • Ξχϝʔγϣϯ͕ऴΘͬͨΒ DPOUFYUDPNQMFUF5SBOTJUJPO USVF UIViewControllerAnimatedTransitioning プロトコル animateTransition(using:) メソッド
  8. ࣮૷ྫ   func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { presenting =

    operation == UINavigationControllerOperation.push // containerView, fromView, toView を取得 let containerView = transitionContext.containerView let fromView = transitionContext.view(forKey: .from)! let toView = transitionContext.view(forKey: .to)! // 詳細画面側のViewを取得し、アニメーション中は非表示にする let detailView = presenting ? toView : fromView toView.alpha = 0 // 詳細画面のImageViewの位置, 遷移用ImageViewの初期位置と最終位置 let detailFrame = CGRect(x: 0, y: 64, width: detailView.frame.width, height: detailView.frame.width)
  9. ࣮૷ྫ   // 詳細画面のImageViewの位置, 遷移用ImageViewの初期位置と最終位置 let detailFrame = CGRect(x:

    0, y: 64, width: detailView.frame.width, height: detailView.frame.width) let initialFrame = presenting ? originFrame : detailFrame let finalFrame = presenting ? detailFrame : originFrame // 遷移中のみ表示させるImageView let transitionImageView = UIImageView(frame: initialFrame) transitionImageView.image = listImageView.image transitionImageView.contentMode = .scaleAspectFill transitionImageView.clipsToBounds = true containerView.addSubview(toView) containerView.addSubview(transitionImageView) containerView.bringSubview(toFront: transitionImageView)
  10. ࣮૷ྫ   // 最初の0.2秒で遷移元の画面を非表示にする // containerViewに追加しているImageViewだけが表示される UIView.animate(withDuration: duration/5, animations:

    { fromView.alpha = 0 }) // 0.2秒後からEaseInOutでImageViewの位置を移動 // 合わせて、一覧に戻る遷移の場合は一覧画面を徐々に表示 UIView.animate(withDuration: duration*4/5, delay: duration/5, options: [.curveEaseInOut], animations: { transitionImageView.frame = finalFrame if !self.presenting { toView.alpha = 1 } }, completion: { _ in // 非表示にした詳細画面を表示
  11. ࣮૷ྫ   if !self.presenting { toView.alpha = 1 }

    }, completion: { _ in // 非表示にした詳細画面を表示 // 遷移中に表示していたimageViewを削除 if self.presenting { detailView.alpha = 1 } else { self.dismissCompletion?() } transitionImageView.removeFromSuperview() transitionContext.completeTransition(true) }) }
  12. ͓·͚6*7JFX1SPQFSUZ"OJNBUPS ʹ͍ͭͯ $PSF"OJNBUJPO $"-BZFSͰͷΞχϝʔγϣϯ 6*7JFX $"-BZFSΛ಺෦ʹ͍࣋ͬͯΔ 6*7JFX1SPQFSUZ"OJNBUPS J04ʙ ͍Ζ͍ΖઃఆͰ͖Δ΍ͭ ಺෦ͰݺΜͰΔ

    ಺෦ͰݺΜͰΔʜʜͱࢥ͏ • ΞχϝʔγϣϯͷҰ࣌ఀࢭ΍ٯ࠶ੜ • ΠʔδϯάͷΧʔϒΛࣗ෼Ͱઃఆ • ಈతʹΞχϝʔγϣϯΛ௥Ճ %BZ !%
  13. ͍͞͝ʹ • ϚΠΫϩΠϯλϥΫγϣϯΛద੾ʹऔΓೖΕΔ͜ͱͰɺ ΞϓϦͷ࢖͍৺஍͕Α͘ͳΓɺϢʔβʔମݧ͕޲্͢Δ • ؤுͬͯεςοϓΞοϓ͍͖ͯ͠·͠ΐ͏ʂ ՝୊Λ ղܾͰ͖Δ εϜʔζʹ ՝୊ղܾ

    ࢖͍উख ՝୊ղܾ͕ շײʹͳΔ ࢖͍৺஍ ҆ఆͨ͠ಈ࡞ ը໘ͷߏ੒ཁૉ΍ ભҠͷ߹ཧԽ ಈ࡞ͷΧΫ͖ͭ ϚΠΫϩΠϯλϥΫγϣϯ
  14. ࢀߟࢿྉ • 6*7JFX "OJNBUJPO$PSF"OJNBUJPO • IUUQTEFWFMPQFSBQQMFDPNKQEPDVNFOUBUJPO7JFX1(@J1IPOF04QEG • IUUQTEFWFMPQFSBQQMFDPNKQEPDVNFOUBUJPO$PSF"OJNBUJPO@HVJEFQEG • IUUQTTUPSFSBZXFOEFSMJDIDPNQSPEVDUTJPTBOJNBUJPOTCZUVUPSJBMT

    • IUUQTRJJUBDPNIBDIJOPCVJUFNTEDDCB • 6*7JFX1SPQFSUZ"OJNBUPS • IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUBOJNBUJPO@BOE@IBQUJDT QSPQFSUZ@CBTFE@BOJNBUJPOT • IUUQTTQFBLFSEFDLDPNIFEKJSPHJOUSPEVDUJPOUP VJWJFXQSPQFSUZBOJNBUPS • IUUQTTQFBLFSEFDLDPNIFEKJSPHVJWJFXQSPQFSUZBOJNBUPSEFTIJYJBO TVSVSJUVUJOBBOJNFTJZPOCJBPYJBO