先上效果
無限輪播.gif
實現(xiàn)思路:
第一種: 在原圖片集合的基礎上, 分別在原數(shù)據(jù)的開始及結(jié)尾處插入一張圖片, 內(nèi)容分別是原圖片集合的最后一張和第一張, 新圖片集合.count = 原圖片集合.count + 2; 當滑動到第一張或者最后一張圖片時, "偷偷地"將當前偏移位置切換到對應圖片的位置(展示第一張圖片或者最后一張圖片的ImageView所在位置), 詳見下圖:
無限輪播方式一.png
核心代碼:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let index = scrollView.contentOffset.x / self.bounds.width
let currentIndex = (index - 1.0).truncatingRemainder(dividingBy: CGFloat(imageBox.imageArray.count - 2)) + 0.5
pageControl?.currentPage = Int(currentIndex) == (imageBox.imageArray.count - 2) ? 0 : Int(currentIndex)
if index >= CGFloat(imageBox.imageArray.count - 1) {
scrollView.contentOffset = CGPoint(x: self.bounds.width, y: 0)
} else if index <= 0 {
scrollView.contentOffset = CGPoint(x: CGFloat(imageBox.imageArray.count - 2) * self.bounds.width, y: 0)
} else if index <= 0.5 { // 此處只是為了在第一張向前滾動到展示最后一張時, pageControl可以及時變化
pageControl?.currentPage = imageBox.imageArray.count - 2
}
}
第二種: 只需要左, 中, 右三個UIImageView, 默認只展示中間位置的UIImageView, 然后動態(tài)調(diào)整UIImageView上應該放置的image; 例如: 剛開始時, 左中右分別放置的是圖片數(shù)組中最后一張,第0張,第1張圖片, 此時用戶看到是第0張圖片, 當用戶向右滑動時, 此時展示應該是第1張圖片,當滑動結(jié)束時, "偷偷地"將scrollView的偏移量調(diào)整為中間UIImageView位置, 同時調(diào)整對應imageView上展示的圖片, 此時左中右分別對應的應該是 第0, 1, 2張圖片; 詳見下圖:
無限輪播方式二.png
核心代碼:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let index = scrollView.contentOffset.x / self.bounds.width
if index >= 2 || index <= 0 {
self.currentIndex = index >= 2 ? (self.currentIndex + 1) : (self.currentIndex - 1)
setImage()
scrollView.contentOffset = CGPoint(x: self.bounds.width, y: 0)
}
pageControl?.currentPage = self.currentIndex
}
第三種: 最簡單, 最不費腦的實現(xiàn)方式了, 簡單粗暴的將圖片數(shù)組成倍的擴充, 沒明白是嗎? 舉個簡單例子: 新圖片集合.count = 原圖片集合.count * 150(一張圖片的情況除外); 然后開始時默認展示的是偏移量為(新圖片集合.count / 2) * 圖片寬度的位置(也是原圖片集合的第一張圖片), 由于這種方法可能需要占用較多的內(nèi)存, 所以建議使用UICOllectionView, 基于其cell的重用機制, 可以降低內(nèi)存占用.
核心代碼:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetIndex = scrollView.contentOffset.x / self.bounds.width
let currentIndex = Int(offsetIndex.truncatingRemainder(dividingBy: CGFloat(self.imageBox!.imageArray.count)) + 0.5)
if Int(offsetIndex) >= actualItemCount {
scrollView.contentOffset = CGPoint(x: self.bounds.width * CGFloat(actualItemCount) / 2, y: 0)
}
pageControl?.currentPage = currentIndex == imageBox.imageArray.count ? 0 : currentIndex
}