contentInsetを設定するとscrollToItem(..)でスクロール移動できないセルが発生する現象を回避するには?
collectionView
で指定セルまでスクロールさせたいのですが、contentInset
を設定すると scrollToItem(at:at:animated:)
メソッドではスクロール移動できないセルが発生して困っております。
問題を分かりやすくするために、以下のような横スクロールのコレクションビューを作成してみました。数字を表示するだけのセルを隙間なく並べたコレクションビューです。(下図にあるセルの境界線はUICollectionViewCell
カスタムサブクラスのサブビュー(UIView
)によるものです。)
「SCROLL」ボタンをタップするとUITextField
に入力した数字と同じitem
まで自動スクロールします。指定セルが中心に表示されるよう、左右に1セル幅分だけcontentInset
を設定しています。
let cellWidth: CGFloat = 50
collectionView?.contentInset = UIEdgeInsets(top: 0, left: cellWidth, bottom: 0, right: cellWidth)
セル3つ分の幅のコレクションビューなのですが、セル1を指定した場合のみ思うように動作してくれません。
【 問題点 】
- セル0の時にセル1を指定すると、スクロールしない
- セル2以上の時にセル1を指定すると、スクロールし、中央がセル0になる
上の例では、「SCROLL」ボタンをタップしたタイミングで、scrollToItem(at:at:animated:)
を呼び出しています。
@objc private func handleScrollButtonTap(_ sender: UIButton) {
if let text = textField.text, let number = Int(text) {
selectedNumberLabel.text = text
// テキストフィールドで指定された番号のセルまでスクロール
let indexPath = IndexPath(item: number, section: 0)
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
textField.resignFirstResponder()
textField.text = nil
}
対策として、セル1のみで発生するので、セル1の場合のみUIView.animate(..)
を用い contentOffset.x
をアニメーションさせて他のスクロールと同様に見せかける方法を試したのですが、
if number == 1 {
UIView.animate(withDuration: 0.2, animations: {
self.collectionView.contentOffset.x = 0
})
}
else {
let indexPath = IndexPath(item: number, section: 0)
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
離れたセルからセル1にスクロール移動する場合に、間のセルが自動補完されないため、数字が消えたりcollectionView
の背景色が見えたりして、スムーズなスクロールに見えません。
UICollectionView
でcontentInset
を設定した場合、すべてのセルへ問題なくスクロール移動するにはどうしたらいいでしょうか?
上の例でいうセル1へのより良いスクロール方法がありましたら、教えていただけませんでしょうか?
よろしくお願いいたします。