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

UICollectionViewのAPIを活用してシンプルなコードにリファクタリングする

hicka04
March 02, 2023

 UICollectionViewのAPIを活用してシンプルなコードにリファクタリングする

「家族アルバム みてね」のコア機能であるメディアを一覧できる画面のレイアウトをリファクタリングしました。 iOS14以降で使える UICollectionView の API を活用して、レイアウト崩れに強くシンプルなコードに変更する方法を紹介します。

hicka04

March 02, 2023
Tweet

More Decks by hicka04

Other Decks in Programming

Transcript

  1. ©MIXI 自己紹介 • 佐藤 光 (@hicka04) • 株式会社MIXI みてね事業部 ◦

    2021/11 中途入社 • 二児の父 • 「家族アルバム みてね(以下 みてね)」の1ユーザー • 好きなもの ◦ ラーメン ◦ ポケモン 2
  2. ©MIXI リファクタリング対象 • アルバムタブ • メディアを一覧できる画面 • ページの種類 ◦ 月ごとのメディア

    ◦ コレクション (1秒動画などのコンテンツ ) • 左右スワイプ or 上部のページタップで遷移 7
  3. ©MIXI アルバムタブを選んだ理由 • 2022/4~ 開発体制をドメインチーム制に変更 (※) ◦ アルバムの基本機能 (メディアのアップロード/閲覧など) ◦

    メディアを使った商品 • アルバムタブに対して手を入れる機会が増えている • 課題: リリース当初から継ぎ足しのコードが多い ◦ いいものを早く届けるのが困難で、どこかで妥協が発生する ▪ 修正に多くの工数がかかるのを許容 ▪ 工数がかからないように仕様を調整 ◦ 画面崩れが発生しやすくなっている 8 ※2022年版 みてねを支えるプロダクト開発体制
  4. ©MIXI 現状の課題を洗い出し • StoryboardでUI作成 ◦ コードレビューがしやすいコードでのレイアウトを推奨 • ViewControllerにロジックが存在 ◦ テストコードが書きづらい

    • CollectionView ◦ CollectionViewLayoutを使った地道なFrame計算 ◦ reloadData で全件更新 ◦ セル利用時に非型安全 • など… 10
  5. ©MIXI CollectionView周りの解決方法の検討 • CollectionViewLayoutを使った地道なFrame計算 ◦ → Compositional Layouts (iOS 13

    +) • reloadData で全件更新 ◦ → Diffable Data Source (iOS 13 +) • セル利用時に非型安全 ◦ → Cell Registration (iOS 14 +) 11 ※2023年3月時点でiOS14以上をサポートしているため、現状使える API限定
  6. ©MIXI Compositional Layouts (iOS 13 +) • Section / Group

    / Item を組み合わせて構造化 ◦ 宣言的にレイアウトを作ることができる • サイズ指定 ◦ 親のN%のサイズ ▪ fractionalWidth / fractionalHeight ◦ Self Sizing ▪ estimated • 位置指定 ◦ Groupの並び horizontal / vertical / custom 13
  7. ©MIXI Diffable Data Source (iOS 13 +) • 更新前後のデータ(snapshot)を比較して差分を取り 必要なセルのみリロードできる

    • 1つのメソッドでデータ更新完結 ◦ reloadItems / reloadSections / reloadData → dataSource.apply(snapshot) • 差分に応じて自動でいい感じのアニメーション 14
  8. ©MIXI Cell Registration (iOS 14 +) • セルの利用が型安全 • 従来の方法のデメリット:

    実行時クラッシュが発生しやすい ◦ 事前にセルを登録していないと… ◦ 表示するセルの取得時にtypoすると… • 各々のプロジェクトでextension実装して解決していた ◦ collectionView.register(CustomCell.self) ◦ collectionView.dequeue(CustomCell.self, at: indexPath) • 公式のAPIで実現できるようになった 15
  9. ©MIXI 成果 • ほぼ同じ仕様のまま約45%までコードを削減 ◦ +507 -1147 • コードの見通しが良くなった ◦

    コード量が少なくなった ◦ レイアウトの記述が宣言的 ◦ データを更新するメソッドが1つに集約された • 特定の条件下で発生していた画面崩れ解消 24
  10. ©MIXI リファクタリングに伴う仕様変更 • スワイプでのページ遷移中のアニメーションを変更 ◦ Diffable Data Sourceを使う場合 UIの状態とデータを一致させた方が実装しやすい ◦

    ピンクのバーではなくOffsetを動かす • チームメンバーやPOに触っていただいた上で許容と判断 ◦ リリース後、この変化をつぶやいている人は見つけられなかった 25 Before After
  11. ©MIXI まとめ • iOS14以上で使えるUICollectionViewのAPIを活用して シンプルなコードにリファクタリングする方法を紹介 ◦ コード量削減 & レイアウト崩れに強い ◦

    現状の仕様を全て満たすのが難しい場合も存在する • メディアを表示するCollectionViewも改善中 → ◦ 今回紹介できなかったAPIも利用予定 NSDiffableDataSourceSectionSnapshot • 今後も利用箇所を増やしていって シンプル & 画面崩れに強いUIを作っていきたい 27