1.說下原理:
1./*初始化/
+ (instancetype)loopScrollViewWithFrame:(CGRect)frame;
將背景collectinview視圖初始化設置 代理和數據源 、 布局
2.在激活initwithFrame后觸發 layoutSubviews
//默認滾動到要顯示的第一張圖片
if (self.imageCollectionView.contentOffset.x == 0) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:1 inSection:0];
[self scrollToIndexPath:indexPath animated:NO];
self.currentIndex = 1;
}
界面展示出來的時候默認 顯示 真實下標也就是從1開始
設置真實數據源 imageList ,然后展示 的 數據源是loopImageList 這里 呢 多出2個對象,0和末尾,設置時 最后 和 起始,setImageList如下
- (void)setImageList:(NSMutableArray *)imageList {
_imageList = imageList;
self.loopImageList = [NSMutableArray arrayWithArray:imageList];
if (imageList.count>0) {
[self.loopImageList insertObject:[imageList lastObject] atIndex:0];
[self.loopImageList addObject:[imageList objectAtIndex:0]];
}
}
核心代碼和思路
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat width = self.bounds.size.width;
//在loopImageList中,有n+2個對象,因此index取offset.x/width后的整數
NSInteger index = scrollView.contentOffset.x/width;
//這個比值很重要
CGFloat ratio = scrollView.contentOffset.x/width;
//從顯示的最后一張往后滾,自動跳轉到顯示的第一張
if (index == self.loopImageList.count-1) {
self.currentIndex = 1;
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.currentIndex inSection:0];
[self scrollToIndexPath:indexPath animated:NO];
return;
}
//從顯示的第一張往前滾,自動跳轉到顯示的最后一張
//這里判斷條件為contentOffset.x和寬的比值,在往前滾快要結束的時候,能達到無縫切換到顯示的最后一張的效果
if (ratio <= 0.01) {
self.currentIndex = self.imageList.count;
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.currentIndex inSection:0];
[self scrollToIndexPath:indexPath animated:NO];
return;
}
if (self.currentIndex != index) {
self.currentIndex = index;
}
NSLog(@"currentIndex = %ld",self.currentIndex);
}
這里的原因是為什么呢?
- 這時候在圖滾動 執行代理 監聽的時候 ,我們的collectionview有設置 pageEnable 分頁屬性很關鍵有分頁動畫。
當偏移量判斷 真實的數據顯示到了最后一張。也就是8 滾到1的時候 ,設置回滾 ,回到默認位置,且沒有動畫。
2.另外一步處理當偏移量 小于 一個極小值 也就是 偏移即將到達 0 的是偶也就是 真實的第一張回滾到最后 一張的時候,設置默認滾動到最后一張。
最重要的一點 這個黑科技 是使用scro 滾動到特定的item所以 在觸發的那一時刻,item就設定死了,scrollViewDidScroll:也就不會再滾動,因為現在的偏移量是一個唯一值。