2021年5月16日PR普通のUINavigationのpushの遷移はわかりやすいしアニメーションも最低限実装されているが、少し単調というか見飽きたというか。カスタマイズしていきたいなと思いました。純正アプリであるAppStoreアプリですが、カードが一覧で表示されてタップすると詳細画面にアニメーションで遷移する、このアニメーションめっちゃかっこいいですよね、是非真似していきたい、実装してみたい、ということで実装してみました。実際には少し違うものが出来上がったのですが、ほとんど同じような挙動です。AppStoreなど標準のiOSアプリは既にSwiftUIで置き換えられているのかもしれないですが、まだまだ知識経験がdeveloper全体の中でも自分としてもまだ十分ではないと感じています。UIKitでは簡単に表現できていたことがSwiftUIではまだまだ出来ないという部分も多くあると思います。実際のプロダクトではUIKitをガッツリと使っていく状態は続くと思うので(趣味のアプリは別として)、今回もUIKitでAppStoreアプリと同じトランジションアニメーションを実装してみました。複雑にはなるので、トランジションのアニメーション自体が初めての場合は、以下の記事のほうがより易しいです。UINavigationControllerでのトランジションや、普通のpresentでのモーダル表示など、すこし飽きてきました。やっ...標準アプリAppStoreの確認(目標の確認)まずは目標とするアプリの挙動を確認してみます。このように、カードが一覧で表示されていて、タップすると、カードが広がりつつ詳細画面に遷移する、詳細画面からの遷移ではカードが縮小していくようなアニメーションがあり、またUIScrollViewのcontentOffsetYが0の状態で下スクロールすると、スクロールの大きさによってカード自体が小さく縮小していくアニメーション、そしてスクロールが一定量超えるとdismissされるようなアニメーションです。以下の動画は実際に今回作成したアプリの挙動です。AppStoreとほとんど同じですが、カードはシンプルにしています。画像をカードいっぱいに表示しており、その上にUILabelを載せているのみです。タップすると同じようなアニメーションで拡大しつつ詳細画面に遷移させています。サンプルアプリの構成要素では実際に実装の解説に入っていきます。必要となる構成要素からです。一覧画面(ListViewController)詳細画面(DetailViewController)カードビュー(CardView)カードビューセル(CardViewCell)カードビューモデル(CardViewModel)カードトランジションマネージャー(CardTransitionManager)今回の実装で重要なのは上記の6つです。一覧画面(ListViewController)まずは一覧画面です。こちらはUITableViewをListViewControllerのviewにaddし、このtableViewにCardViewCellを表示しています。サンプルなのでセルの数は3つと決め打ちしています。}}AutoLayout特にポイントというほどのポイントもないのですが、今回もSnapKitを使っています。SnapKitは、コードでAutoLayoutを少ない記述量で実装できるライブラリです。falseが必要になります。CardViewModelUITableViewに表示するセルですが、上記のように、決め打ちで3つとしています。先にCardViewModelのコードを記載します。String}これだけです。必要最低限だけを実装しています。imageは、カードの背景に目一杯表示する画像です。Assets.scassetsに画像を3つ格納し、それを読み込んでいるだけです。titleは、カードの真ん中に大きく表示するUILableに使用しています。subtitleは、カードの左下に小さく表示するUILabelに使用しています。なくても問題ありません。CardViewModelのイニシャライズCardViewModelの定義は上記のみで、ListViewControllerではこのCardViewModelをイニシャライズしています。CardViewModelには、自動的にメンバーワイズイニシャライザーが実装されます。CardViewModel(と打ち込むとコード補完でイニシャライズ用コードが表示されますので、補完候補をそのまま使ってしまいます。propertyです。これは後にトランジションアニメーションを実装するときに使用します。詳細画面(DetailViewController)次は遷移先の詳細画面です。本記事のメインはアニメーション部分ですが、この詳細画面でもいくつかのポイントに触れておきます。元のアプリであるAppStoreアプリの挙動を確認してみてください。詳細画面では、まずスクロールが可能で、詳細画面で開いたアプリなどの詳細な情報が確認できるようになっています。ここでは、詳細説明の文章や画像などが表示されていますが、今回実装するアプリでは文字列(UILabel)のみを表示するようにします。立体的にみると次のような実装になっています。UIScrollViewCardViewUILabelUIButton主な構成要素はこの4点です。DetailViewControllerのviewの上にはUIScrollView、UIScrollViewの上部には今回独自で実装するCardViewと閉じる用のUIButton、そしてCardViewの下側には、UILabelという構成になっています。DetailViewControllerのイニシャライズ詳細画面では、独自クラスの1つのインスタンスを詳細に表示するという目的の画面なので、独自クラスの1つのインスタンスでDetailViewControllerをイニシャライズするように実装しています。nil)}snapshotView次に、スクロールでdismissするときのアニメーションのため、snapshotViewを実装しておきます。imageView}()AppStoreアプリの挙動とは少し違う部分がありますが、概ね同じです。UIScrollViewのスクロール部分が一番上にある状態でさらに下側にスワイプすると、DetailViewController自体が小さく縮小し、スクロール量が閾値を超えると、dismissを発火するようにします。このときに縮小するUIはDetailControllerのviewそのものではなく、そのviewのUIをUIImageとしてコピーし、その画像を縮小していく、という方法をとっています。}}役割分担のため、スナップショットのUIImageを作成するためのextensionを実装しておきます。view.frame.height)}あとは、関数を定義しておき、トランジションの中すぐに呼び出せるようにしておきます。UIScrollViewの実装スクロールの話も出たのでここで記載しておきます。上述の通り、スクロールでdismiss出来るように実装していきます。このとき、isTrackingによって、scrollView.bouncesを操作したり、スクロール量によって、諸々のviewの表示/非表示切り替え、snapshotViewの表示/非表示、縮小などを実装していきます。スクロール量が閾値を超えると、dismissします。}}なお、詳細画面ではステータスバーを非表示にしています。何かしらの一覧画面がありそこから詳細画面に遷移する場合を想定します。一覧画面で表示するCardViewを実装していきます。}}特に注意点などはないですが、こちらもCardViewModelでイニシャライズするように実装しています。}}CardView自体をセルの上にaddしており、cornerRadius及び上下左右のスペースをAutoLayoutで追加しています。カード感を表現するために、CardViewの裏側にshadowViewもaddしています。これで、CardViewをCardViewCellで表示するときには、影と角丸が追加され、詳細画面ではCardViewのみなので角丸と上下左右のスペースはなく、画面いっぱいに表示されるような実装になります。前回の記事と色々説明が重複するところがあるので、ポイントだけ記載します。UINavigationControllerでのトランジションや、普通のpresentでのモーダル表示など、すこし飽きてきました。やっ...アニメーションのポイントAppStoreアプリのアニメーションを確認して実装の方向性を検討します。今回実装することにしたポイントは以下の通りです。一覧から詳細にアニメーションする時、カードが少し小さくアニメーションしてから詳細画面に向けて拡大する。詳細から一覧にアニメーションするときは、すなおに、元の大きさにアニメーションするのみ。一覧から詳細にアニメーションするとき、裏側に白いViewがアニメーションで現れ、カードが広がっていくアニメーションを実装する。その際、裏側に表示されている一覧画面は徐々にblur効果がかかってぼやけるように見える。一覧から詳細、詳細から一覧の両方向のアニメーションにおいて、少しバウンドするようなアニメーションになっている。}}一番大事な詳細説明で、力尽きました。ココナラココナラというサービスをご存知ですか?ココナラは、プログラミングやウェブ制作、デザインなどの専門知識を持つ人たちが、自分のスキルを活かしてサービスを提供する場所です。初学者の方でも気軽に相談できるため、自分のスキルアップにも最適です。自分自身もココナラでサービスを提供することができ、収入を得ることができます。