in my case I fixed it so:
here I detect if my cell is fully visible, and if it's not so - move to it. (without "jumping")
let cellRect = collectionView.convert(cell.frame, to: collectionView.superview)
if !collectionView.frame.contains(cellRect) {
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredHorizontally)
return collectionView.reloadData()
}
here, I hold my contentOffset:
let currentContentOffSet = collectionView.contentOffset
if #available(iOS 12.0, *) {
UIView.animate(withDuration: 0) {
collectionView.reloadData()
collectionView.performBatchUpdates(nil, completion: { _ in
collectionView.contentOffset = currentContentOffSet
})
}
} else {
UIView.animate(withDuration: 0) {
collectionView.reloadItems(at: [self.lastSelectedIndexPath, indexPath])
collectionView.contentOffset = currentContentOffSet
}
}
it helps move to cells if cells became visible recently (or already visible) and I tap to the cell. Also without "jumping" (without resetting contentOffset)
Also you can try this in collectionViewController:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) else { return }
if lastSelectedIndexPath != indexPath {
let cellRect = collectionView.convert(cell.frame, to: collectionView.superview)
if !collectionView.frame.contains(cellRect) {
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredHorizontally)
} else {
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .init())
}
collectionView.deselectItem(at: lastSelectedIndexPath, animated: false)
lastSelectedIndexPath = indexPath
}
}
and this in collectionViewCellModel:
override var isSelected: Bool {
didSet {
switch self.isSelected {
case false:
case true:
}
}
}