Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

カスタムトランジションやアニメーションを活用した「写真を生かすUI」のサンプル

1,072 views

Published on

shibuya.swift #7での登壇資料になります。

昨年のAdventCalendarでも触れたカスタムトランジションとアニメーションを活用して写真を生かすようなUIを作る際のポイントに関してピックアップしたものになります。

今回は特にカスタムトランジションを活用した処理部分での実装に重点を置きModal遷移時及びNavigationControllerでのPush/Pop時のケースに関して解説をしています。

★実装サンプルに関する詳細解説
http://qiita.com/fumiyasac@github/items/04c66743a3c829d39b1f

★サンプルのリポジトリ
https://github.com/fumiyasac/mediaStyleTableViewSet

Published in: Technology
  • Be the first to comment

カスタムトランジションやアニメーションを活用した「写真を生かすUI」のサンプル

  1. 1. カスタムトランジションやアニメーションを 活用した「写真を生かすUI」のサンプル Shibuya.swift #7 2017/01/26 Fumiya Sakai
  2. 2. 自己紹介と簡単な経歴など ✦ 今までの仕事履歴(本業) 石川県金沢市生まれ 本業はサーバーサイドのプログラマ ※Rails&PHP使い 26歳〜32歳: Webプログラマ(PHP & Rubyがキャリア長い) 23歳〜25歳: Webデザイナー兼ディレクター チャンスがあればiOSアプリ開発も絶賛やってみたい! 趣味:シルバーアクセサリー集め・スイーツ作り・アプリ開発 女子向け・グルメ・エンタメ関連のお仕事が多い Qiita : http://qiita.com/fumiyasac@github Github : https://github.com/fumiyasac ✦ 酒井文也(さかい ふみや) 東京(大塚)住まいの32歳 こんな格好を普段からしているので 遊び人に見られますがエンジニアです。 文系卒に思われますが 実は数学科で理系卒です。 めっちゃお酒好きそうに見えますが ビール苦手でお酒も超弱いです。 今でもたまにUIまわりとか触りたく なることがあったりなかったり 今年の4月からフリーランスです。 (割とお堅い感じの会社にいます) 最近のはまっている食べ物は カボチャと担々麺と甘栗です。 最近はSwift以外ではRailsやLaravel・CakePHP・Node.jsなんかも
  3. 3. これまでに作ったもの(ネイティブアプリ) ① 簡易家計簿アプリ「Coffre」 ② ゲームアプリ「10秒虫食い算」 ・カレンダーを自作しています ・シンプルなお小遣い帳感覚で支出管理できます ・全問正解者ほとんどいません… ・不定期ですがコラムも書いています ・サーバーサイドはRuby on Railsを使用 http://www.coffre.me/ ・デザインにもこだわってみました(特にグラフ) ・実はちょっとバグがあります。 ・問題は今後追加予定(現在110問収録) 個人的にはなりますが、他にもアプリ・Webサービスなど開発中です(2017年も宜しくお願いします) ・サイト等は次回のアップデートで公開予定 http://blog.just1factory.net/services/284 ・若干の中毒性を含みます
  4. 4. カレンダーが好きでライブラリを作りました 日本の祝祭日を計算で出してくれる ・カレンダーアプリ等での活用を想定 ・シルバーウィーク・ゴールデンウィークも対応 ・ハッピーマンデー法の施行も対応 ・春分の日・秋分の日にも対応 ・過去の祝祭日もおおむね考慮はしている 構想や基本実装は僕ですが、他に4名のContributorのお力添えがあり実運用できるレベルになりました! 職人の手作業で計算しております! ・HTTP(HTTPS)通信は不要 ★CalculateCalendarLogic ver0.1.3 【最新情報】最近はmacOSのサポートがされました! ※CocoaPods / Carthage経由で導入できます。 ・Github: https://github.com/fumiyasac/handMadeCalendarAdvance ・実装解説: http://qiita.com/fumiyasac@github/items/33bfc07ad36dfffcdf8f 【2017年】Swift3系への正式対応をしていますので是非README等を参考に導入してみてください!
  5. 5. ✦ CustomTransitionの基本事項や概念理解 CustomTransitionで遷移時の表現を彩る CustomTransition用の外付けクラスを用意し、遷移元のViewController等でtransitionDelegateを適用 [iOS7] 簡単にできる画面遷移のカスタマイズ http://natsuapps.com/note/2013/12/ios7-transition.html 処理実体処理と遷移時の適用処理が別れているケースが多い&プロトコル名が長いので初見だと面食らった ★重要なプロトコル ・UIViewControllerAnimatedTransitioning(アニメーション用のコントローラー) ・UIViewControllerContextTransitioning(画面遷移のコンテキスト ※遷移先・遷移元の情報が入っている) ★CustomTransition用の外付けクラスで設定するもの 【参考】 ・UIViewControllerTransitioningDelegate(画面遷移のデリゲート) アニメーションの時間 アニメーションの実装 アニメーションの実体は、画面遷移の コンテキストから作成するContainerView UIViewControllerAnimatedTransitioningを使って画面遷移アニメーションを作る http://qiita.com/kitoko552/items/4c0e411ff6224090db87
  6. 6. import UIKit //画面遷移時に使用するアニメーションの実装をUIViewControllerAnimatedTransitioningを採用したクラスにて行う class TransitionController: NSObject, UIViewControllerAnimatedTransitioning { //アニメーションの時間を定義する internal func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return (遷移アニメーションの時間) } /** * アニメーションの実装を定義する * この場合には画面遷移コンテキスト(UIViewControllerContextTransitioningを採用したオブジェクト) * → 遷移元や遷移先のViewControllerやそのほか関連する情報が格納されているもの */ internal func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { (この中に画面遷移時のアニメーションを行う実体の処理を記載する) } } ✦ CustomTransitionの処理をまとめたクラスを用意 CustomTransitionの外付けクラスの概要 アニメーション実体をそれぞれの遷移のタイミングで適用する形なのでanimateTransion内に処理を記載する ★アニメーションを実装するクラスの雛形はざっくりとこんな感じ NSObjectを継承 & UIViewControllerAnimatedTransitioningを適用 このクラスのメンバ変数として遷移元 ⇄ 遷移先を管理する変数を作る【しておくと良いもの】
  7. 7. ✦ 処理の実体はContainerViewを作成しその中に表示対象を入れる CustomTransitionの組み立てポイント 画面遷移時に表示したい or 動かしたいUI要素を取得できるので、その各要素をContainerViewへ追加する形 ★画面遷移のコンテキストからアニメーション実体及びViewControllerを取得 各遷移元及び遷移先ViewControllerを取得し、その中のUI要素に関するものを取 得する。取得した要素をaddSubViewをしてアニメーション処理を適用する流れ。 ・遷移元 それぞれの画面遷移に関する要素はtransitionContextから取得し、その要素に対しアニメーション アニメーション実体の ContainerView //アニメーションの実態となるコンテナビューを作成 let containerView = transitionContext.containerView addSubView アニメーション完了時にはtransitionContext.completeTransition(true)とする //遷移元のControllerの取得 let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) //遷移先のControllerの取得 let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) ・遷移先 取得して追加したものに対して UIView.animate( … を適用する
  8. 8. class SampleController: UIViewController, UIScrollViewDelegate, UIViewControllerTransitioningDelegate { //・・・(省略)・・・ //カスタムトランジション用クラスのインスタンス let transition = CustomTransition() //サンプルのボタンアクション func sampleAction(_ sender: UIButton) { //カスタムトランジションを適用した画面遷移を行う let contentsDetail = storyboard!.instantiateViewController(withIdentifier: "ContentsDetailController") as! ContentsDetailController garellyDetail.transitioningDelegate = self self.present(contentsDetail, animated: true, completion: nil) } //・・・(省略)・・・ } ✦ 遷移先のViewControllerにtransitionDelegateを適用する CustomTransitionをModal遷移へ適用する① 遷移元のViewController側にCustomTransitionを利用した遷移に関する処理を適用させる処理を記載する形 ★UIViewControllerTransitioningDelegateの適用と遷移時のアクションの設定例 CustomTransitionのクラスを適用するための下準備 遷移元→遷移先への遷移タイミングでtransitionDelegateの宣言 UIViewControllerTransitioningDelegateの記載のみ (処理は遷移元のViewController)【遷移先の設定】
  9. 9. /** * Modal遷移時の実装参考:iOS Animation Tutorial: Custom View Controller Presentation Transitions * https://www.raywenderlich.com/113845/ios-animation-tutorial-custom-view-controller-presentation-transitions */ //進む場合のアニメーションの設定を行う internal func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { //遷移時にCustomTransitionで必要な値を引き渡す等の処理を行う transition.presenting = true return transition } //戻る場合のアニメーションの設定を行う internal func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { transition.presenting = false return transition } ✦ UIViewControllerTransitioningDelegateプロトコルを適用 CustomTransitionをModal遷移へ適用② present / dismissを判定する設定をCustomTransitionのクラス内で管理できるようにしておくのがポイント ★animationControllerメソッドでpresent & dismiss時の動きを設定する CustomTransitionクラス内のメンバ変数:presenting(Bool型)で決定【遷移の方向(present/dismiss)】
  10. 10. ✦ 詳細に関しましてはサンプルのデモを行います。 今回のサンプルの概要 今回は動きがある程度わかりやすいように合いそうなデザインと一緒にサンプルコードを作成してみました CustomTransition + UINavigationBar (Design Customize) ★今回のサンプルについて
  11. 11. ✦ 詳細解説に関しても下記の文章にまとめていますので併せてどうぞ 今回のサンプルと主な機能と詳細 CustomTransitionやアニメーションの使い方以外の部分も色々盛り込んでみましたので参考になれば幸いです Github:https://github.com/fumiyasac/mediaStyleTableViewSet ECやメディア系のアプリでよくある遷移時のカスタムトランジションやアニメーションを活用した 「写真を生かすUI」のサンプル: http://qiita.com/fumiyasac@github/items/04c66743a3c829d39b1f ・UICollectionViewCellのタップ時にUIViewControllerAnimatedTransitioningを活用した  画面遷移処理を用いて、画像を拡大させて遷移先のUIViewControllerを表示する動き ・SwiftyJSON & Alamofireを利用したAPI通信 & アニメーションとスレッド・画像キャッシュの活用 ・UINavigationControllerのデザインカスタマイズと設定に関する部分 ・カスタムしたポップアップの表示 ・遷移先から戻る際も同様にUIViewControllerAnimatedTransitioningを活用した  画面遷移処理を用いて、遷移元のUICollectionViewの画像表示エリアに画像を戻す動き ・ボタンに設定した下線が押下のタイミングで文字幅に合わせてた位置に移動 今回の資料では遷移とアニメ ーションの関連部分を中心に まとめています。 ★主な実装機能 ★サンプル&詳細解説
  12. 12. ✦ Push / Pop時のアニメーションをカスタマイズするケース UINavigationBar + CustomTransition① Push / Pop時にCustomTransitionを適用させるために独自のUINavigetionに関するクラスを実装しておく ★遷移アニメーションの実体クラス & NavigationControllerを継承した適用するクラス TransitionController.swift TransitionNavigationController.swift AppDelegate.swift NavigationControllerの遷移(Push/Pop)をする際にはCustomTransitionが適用される形にする 遷移アニメーションの実体を実装するクラス 状態(Push / Pop)管理用メンバ変数: forward と遷移の際にアニメーションをする画像情報を 引き渡すロジックが実装されている。 UINavigationControllerを継承 & UINavigationControllerDelegateプロトコルを適用したクラス //UINavigationControllerでUIViewControllerAnimatedTransitioningを実装した独自アニメーションを使用する際に使用する internal func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { … } rootViewControllerの設定時にTransitionNavigationControllerクラスを適用させる(今回は全体に適用) 【この実装のポイントとなるメソッド】 ※この部分の設定は実装や設計次第で行う
  13. 13. ✦ UIViewControllerAnimatedTransitioningの独自アニメーション適用 UINavigationBar + CustomTransition② TransitionControllerの内容はPush / Pop時の処理を分けて画像が浮き上がって拡大 / 縮小する形にする ★Push / Popでの画面遷移時にCustomTransition用のクラスを適用させる処理 //UINavigationControllerでUIViewControllerAnimatedTransitioningを実装した独自アニメーションを使用する際に使用する internal func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { ����//TransitionControllerのインスタンスを作成する let transitionController = TransitionController() �//操作のenum(TransitionController内で定義)の値に応じてpushかpopかを決定する switch operation { case .push: transitionController.forward = true return transitionController case .pop: transitionController.forward = false return transitionController default: break } return nil } } TransitionController.swift (ポイント1): 画面遷移を行うメソッドが実行される タイミングでUICollectionViewCellの タップで選択した画像を作成する (ポイント2): 画面遷移のアニメーションが行われる タイミングで作成した画像の大きさに 関するアニメーションを行う
  14. 14. ✦ 処理の実体はContainerViewを作成しその中に表示対象を入れる UINavigationBar + CustomTransition③ 遷移元の情報をアニメーションが完了した時に、実体のContainerViewから削除する処理を忘れないで行う ★遷移時の動き及び実装時の注意点のまとめ 一覧画面 遷移処理の設計について 詳細画面 CustomTransition 進むとき(Push): UICollectionViewの画像が拡大されて上に表示 & その他 の部分はフェードインで表示 戻るとき(Pop): UICollectionViewの画像が縮小されて元の位置に戻る & その他の部分はフェードアウトで表示 UICollectionViewのセルタップ時に選択したセルの画像を取得できる形にしておく ※設計時のメモ書きや展開図・平面図はQiita参照 UICollectionViewCellの画像が抜き出て 詳細画面が表示されるアニメーション! (注意)遷移アニメーションが終わった後に遷移元のViewに関する部分は消しておくこと 詳細画面の画像表示エリアに合わせた画像の遷移を画面のフェードインアウトと一緒に行う
  15. 15. ✦ NavigationBarのカスタマイズに関する設計(一覧画面) UINavigationBar + CustomTransition④ NavigationControllerをカスタマイズした時にはデザインによりNavigationBar部分の調整が必要な場合も ★アニメーションの仕方によってはNavigationBarのカスタマイズが必要になる NavigationBarの背景を透明にしておく (左右のBarButtonItemやアクション定義はコードで行う) 一覧画面 NavigationBar UIView ViewController.swift タイトル表示エリアやヘッダーはUIViewで似せて作成 UIViewの高さは64でgreyの罫線を入れる (addSubViewをコードで行うと左のような階層にする) UICollection View UICollectionViewの上下スクロールでNavigationBarとUIView をアニメーション付きで隠れる or 再表示をさせる実装 NavigationBar等のカスタマイズ 【Swift】Navigation Barの設定。バーの色や背景画像をカスタマイズする。 http://hajihaji-lemon.com/smartphone/swift/uinavigationbar_setting/
  16. 16. ✦ NavigationBarのカスタマイズに関する設計(詳細画面) UINavigationBar + CustomTransition⑤ NavigationControllerをカスタマイズした時にはデザインによりNavigationBar部分の調整が必要な場合も ★透明なNavigationBar上に写真を重ねるために戻るの矢印だけにする NavigationBarの背景を透明にしておき矢印の戻るボタン を左端に設定する(Backや前ページのタイトルがない) 詳細画面 NavigationBar 写真 DetailController.swift UITableView & FooterMenu 戻るボタンのカスタマイズ UINavigationBarの戻るボタンのカスタマイズまとめ http://qiita.com/STAR_ZERO/items/b17bb7d78b37cb8622ed UINavigationBar custom back button without title https://goo.gl/oxYfkf NavigationBar関連の設定場所 一覧・詳細のViewControllerでのNavigation関連の設定は、ナビゲー ションの透明化(viewWillAppear内) AppDelegete.swiftでのNavigation関連の設定は矢印の置き換え
  17. 17. ✦ 文字列データ&フォントの種類と大きさから文字の横幅を取得 ナビゲーション部分のUIがシンプルな場合には、アニメーションや色を工夫することで目立つポイントになる ★UIScrollViewに敷き詰めたUIButtonのテキストを元に下線の大きさを決定する おまけ:詳細画面の文字幅に合わせた下線ナビ実装 //取得したテキスト文字列とフォントから文字列の幅を取得する fileprivate func getCharacterWidthValue(string: String, font: UIFont) -> Int { let size = string.size(attributes: [NSFontAttributeName : font]) return Int(size.width) } //ボタン表示テキストとスクロールビューの表示エリアから動くラベル(下線)のX座標を取得する /** * 引数は下記の通り: * scrollViewLayoutWidth(Int型) : ボタンを入れたスクロールビューの幅 * separateValue(Int型) : ボタンを入れたスクロールビューの幅で表示されるボタンの数 * page(Int型) : 現在のページ番号(0..n) * charWidth(Int型) : ボタンに表示している文字の幅 */ fileprivate func getMovingLabelPosX(scrollViewLayoutWidth: Int, separateValue: Int, page: Int, charWidth: Int) -> Int { //★詳細は省略 (動くラベルのX座標位置) = (ボタンを入れたスクロールビューの幅 ÷ ボタン数 ÷ 2) + (ボタンを入れたスクロールビュー の幅 ÷ ボタン数 × 現在のページ番号) - (ボタンに表示している文字の幅 ÷ 2) return positionX } ターゲットの文字列に.sizeメソッドを適用する UIScrollView内に配置した動くラベルのアニメーション処理の中にX座標の位置を決めるメソッドを記載する形にする ※下線ナビゲーション部分以外につな ぎ部分ではアニメーションを仕込んだ 箇所の一覧。 ・NavigationBar等を隠す ・ポップアップ表示時 ・CollectionViewスクロール時
  18. 18. ✦ 今回のサンプル作成の上で参考になった資料一覧 この他にも良い動き&心地の良いアニメーションの実装事例をご存知の方がいましたらご教授くださいませ! 参考資料などのアーカイブ ★実装サンプルやその他CustomTransition実装で参考にできそうなものをまとめました 画像がズームインしながら画面遷移するSwiftライブラリを公開しました http://qiita.com/WorldDownTown/items/2ffe6324689533745373 【実装時にインスパイア&参考にさせて頂いたサンプル】 SwiftでiPhone標準写真アプリのアニメーションを再現してみる https://developers.eure.jp/tech/zoom_animation/ Introduction to Custom View Controller Transitions and Animations http://www.appcoda.com/custom-view-controller-transitions-tutorial/ 【その他遷移時アニメーション処理の参考】 【iOS Swift入門 #209】UINavigationControllerの画面遷移をカスタムする http://swift-studying.com/blog/swift/?p=1352 Design Teardown: Zooming Icons http://blog.matthewcheok.com/design-teardown-zooming-icons-preview/ Swiftのバージョンが古い ものに関しては適宜Swift3で 置き換える形にしました。
  19. 19. ✦ 必要以上に多く動きすぎないようなさじ加減をする アニメーション実装での自分なりの心がけ 入れ過ぎてしまうとUIにまとまりがなくなったり、デザインと調和しない形になるので用法容量には注意を ★アニメーション秒数におけるパラメータの微調整 (よく使うパラメータ値) ・0.16 or 0.26 ※かなり早めの切り替わりやスクロールに伴うアニメーションの場合 ・0.36 or 0.48 ※コンテンツの開閉時等で心持ちゆっくり目にしたい(上の値だと早すぎると感じた時) ・0.64 ※タメのある切り替わりや画像のクロスフェードをゆっくりとしたい場合 【注意】くどいようで恐縮ですがここは個人的な所感の部分なのであくまで参考としてお楽しみください。 さじ加減を見誤るとかえって下品に捉えられてしまう場合を作ってしまったことが多々あった…(体験談) ★指の動きと連動するUIパーツ部分とのさじ加減 ★1画面に必要以上に入れすぎない ・普段何気なく見ているiOSアニメーションからアプリのUXを考えてみよう! https://blogs.adobe.com/creativestation/web-xd-ios-animation-examples 指の動きからのアクションがトリガーとなる場合は遅れがあまりないように実装する
  20. 20. ✦ CustomTransitionの活かし方次第で画面遷移時の様々な表現が可能 今回のまとめ ご清聴ありがとうございました!またこのような機会があった際には是非ともよろしくお願い致します! ★気持ちの良いアニメーションを伴う画面遷移はUIでも面白い部分 写真表示や画面の切り替わりをカスタマイズすることでUIの綺麗さやかっこよさを活かす表現が可能 ★NavigationControllerを伴う場合はNavigationBarの表示に関する考慮が必要 Modal時は行き帰りの考慮だけでOKな部分もNavigationControllerを挟む場合は考慮事項が結構出てくる ★デバッグ時にはCustomTransitionの内部処理には注意 遷移時のContainerView内に画面遷移時に表示完了時に不要なアニメーション追加要素がないかは注意 ★自分ルール 【良いアウトプットのために】 発表・登壇時はこの中のいずれか2つを 絶対に準備するルールを設けています!

×