2023-03-29こんにちは。WEAR部iOSチームの小野寺です。先日CollectionViewで実装しているトップページを改修しました。自動)によってコンテンツを切り替え可能にしました。横スクロールによってコンテンツを切り替える仕様なので、CompositionalLayoutで実装しました。上記の方針で進めていく中で、困難な実装に直面したので紹介します。最初に直面した問題が、セクション全体に対するViewの装飾です。今回画像の赤枠部分について、次のように改修が必要になりました。NSCollectionLayoutBoundarySupplementaryItemを使用しました。~~}追加したViewのy座標を、セクションの乗せたい位置(decorationViewHeight)までずらすことで、セクション全体へかかるようにしています。ここではまだ、高さが変わることを考慮していないので、内容によってはレイアウトが崩れてしまいます。Viewの高さを計算する対応を追加し、コンテンツの表示に必要な高さを確保します。~~}追加したcalcViewHeight()をdecorationViewHeightへ反映させます。~~}追加したcalcViewHeight()をdecorationViewHeightへ反映させます。~~}コンテンツの内容によって高さを取得する必要があるのでレイアウト調整にコストがかかっています。OSによってはフッターが非表示になるさらに、iOS14.5未満のOSバージョンで、フッターがセルの裏に隠れてしまう問題もありました。この事象に対しては、UICollectionReusableViewを使った対応が取れませんでした。今回は後にターゲットOSを上げる予定があった為、暫定対応としてUICollectionReusableViewに直接実装したコンテンツをカスタムUIViewとして切り出しました。事象が発生するバージョンではUICollectionReusableViewは使用せず、このカスタムUIViewをCollectionViewのSubViewとして扱う改修で対応しました。コンテンツの自動スクロールレイアウトの改修の次は、自動でコンテンツをスクロールさせる機能の追加です。自動スクロールの対応は、はじめに以下の方針で検討しました。一定時間でスクロールできるように、Timerを追加して定周期でスクロール処理を呼び出す。スクロール処理は、scrollToItem(at:at:animated:)をデフォルトのアニメーションを有効にして、コンテンツをスクロールさせる。true)}実際動作させてみたところcollectionView.contentOffset.yが、アニメーションの度に改修したセクションのデフォルトの位置へと、引き戻される問題が発生しました。第1引数で渡しているindexPathにありました。スクロール先の指定にindexPathが使用されることで、x座標、y座標それぞれに対してscrollToItemが作用してしまいます。これによりCollectionViewの垂直方向が、少しでもスクロールされた状況下の場合に、事象が発生してしまいました。問題を解消するために、今回はscrollToItem(at:at:animated:)のデフォルトのアニメーションは使わず、次のような自作アニメーションを実装しました。}}scrollToItemでのindexPathの更新とy座標をもとに戻す対応を1つのアニメーションとして実装することで、引き戻される問題を回避しています。先頭へ戻るアニメーションにコストがかかるここまでの対応で、自動で次のコンテンツへ切り替える対応ができました。次に最後のセルまで表示させたら、先頭に戻るアニメーションが必要です。戻る処理についてもscrollToItem(at:at:animated:)のアニメーションをそのまま使用できれば、簡潔に対応可能です。(第1引数へ先頭のIndexPathを指定することで、コンテンツが最終位置にいる状態から、アニメーション付きで一気に先頭へ戻す挙動を実現できます)しかし自作アニメーションを使用する場合は、次のような変更が必要になりました。