I have a game where I need to have a board of letters continuously scrolling, and looping through a set of data (A, D, X, S, R, P, F, G, H, Y, W, M
) (Like this:
Infinite scrolling in collection view can be achieved with a very easy technique.
Note: This technique is reportedly not working from iOS 12. For better results I am adding a new method after explaining this one.
1) Return a huge number in numberOfItemsInSection delegate method of collection view.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
return Int(INT_MAX)
}
2) Modulo the number of items in collection view with the count of your array or dictionary whatever you are using to get repeating data.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:
cellIdentifier, for: indexPath)
let displayText = indexPath.row % 10
cell.displayLabel.text = String(displayText)
return cell
}
Here i have no data thus i am using indexPath.row to display the row number in my label.
Suppose i have 10 data to display and currently i have huge number of items so i modulo 10 with number the current item. you can modulo the row with count of your array or dictionary as below:
let displayText = aryData.count % 10
Now explaining another technique which will work in any iOS and will give better output:
1) multiply the number of items in array by 2 and then we need to play with the content offset of collectionview. I am posting the code below on how to handle this technique.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return aryData.count * 2
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = colView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! colViewCell
var index = indexPath.item
if index > aryData.count - 1 {
index -= aryData.count
}
cell.displayLabel.text = aryData[index % aryData.count]
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
// if collection view scrolls vertically, use offset.y else comment below code
var offset = collectionView.contentOffset
let height = collectionView.contentSize.height
if offset.y < height/4 {
offset.y += height/2
collectionView.setContentOffset(offset, animated: false)
} else if offset.y > height/4 * 3 {
offset.y -= height/2
collectionView.setContentOffset(offset, animated: false)
}
// if collection view scrolls horizontally, use offset.x else comment below line of code
// In my case the collectionview scrolls vertically this I am commenting below line of code
// let width = collectionView.contentSize.width
// if offset.x < width/4 {
// offset.x += width/2
// collectionView.setContentOffset(offset, animated: false)
// } else if offset.x > width/4 * 3 {
// offset.x -= width/2
// collectionView.setContentOffset(offset, animated: false)
// }
}
Below is the output of this code.
Hope this will help you :)