1 使用UIScrollview實現無限輪播原理算法
在開發中常須要對廣告或者是一些圖片進行自動的輪播,也就是所謂的無限滾動。小程序
在開發的時候,咱們一般的作法是使用一個UIScrollView,在UIScrollView上面添加多個imageView,而後設置imageView的圖片,和scrollView的滾動範圍。數組
之前的作法:oop
通常而言,輪播的廣告或者是圖片數量都不會太多(3~5張)。因此,並不會太多的去考慮性能問題。可是若是圖片過多(好比有16張圖片,就須要建立16個imageView),那麼就不得不考慮性能問題了。性能
更甚,若是深刻作一個圖片瀏覽的小程序,那麼可能會處理成百上千張圖片,這會形成極大的內存浪費且性能低下。優化
圖片數量衆多:動畫
當用戶在查看第一張圖片的時候,後面的7張建立的時間太早,且用戶可能根本就沒機會看見(看完前面幾張就沒有興趣再看後面的內容 了)。atom
優化思路:只有在須要用到的時候,再建立,建立的imageView進行村循環利用。比較好的作法,不論有多少張圖片,只須要建立3個imageView就夠了。code
使用UIScrollView來實現,首先設置三個固定的UIImageView(下文分別用L、M、R代替)放入一個UIScrollview中,M老是顯示當前要顯示的圖片,而L和R根據M的變化而變化。orm
固然,還須要一個依次存儲圖片信息數據的數組(如下簡稱array),用於給L、M、R三張試圖提供數據源。
舉例:
循環輪播0,1,2,3 這四張圖片,當M顯示第0張時,將4賦給L,將2賦給R。
初始狀態
則在此時,在後臺將M的圖片設置爲1,將UIScrollview的偏移量設置成初始狀態。接着將L設置爲0,R設置爲2。這裏的UIImageView的image變化和UIScrollView偏移量設置都不能開始UIView的動畫效果。最終的現實效果以下圖:
L取得圖片是(index+ array.count)%array.count,
RM取得圖片的索引是(index+ array.count -1)%array.count,
R取得圖片是(index+ array.count + 1)%array.count,
2 使用CollectionView實現無限輪播的具體實現
本文介紹使用Collectionview來實現無限滾動的循環利用。它支持垂直和水平方向上的滾動。
今天爲何寫這個呢,以前寫過項目用scrollView封裝寫過輪播圖,可是感受不是很好,並且傳值也很很差寫,因此今天用collectionView寫的輪播圖,傳值也非常好寫的。
5517BA7A-0DE8-43B6-8C97-7BACA687416D.png
<1>先定一些咱們須要的屬性
@property (nonatomic, retain) UICollectionView *collection; @property (nonatomic, retain) NSMutableArray *marr;// 存圖片的數組 @property (nonatomic, retain) UIPageControl *page; @property (nonatomic, retain) NSTimer *timer; // 調用的一些方法 - (void)viewDidLoad { [super viewDidLoad]; [self createCollectionView]; [self createPhone]; [self createPage]; [self addTimer]; // Do any additional setup after loading the view, typically from a nib. }
<2>//先作一些事前工做,把collectionView鋪好
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init]; layout.itemSize = CGSizeMake(WIDTH, 300); layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; layout.minimumLineSpacing = 0; self.collection = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, 300) collectionViewLayout:layout]; [self.view addSubview:self.collection]; self.collection.backgroundColor = [UIColor whiteColor]; self.collection.pagingEnabled = YES;//開啓翻頁效果 self.collection.delegate = self; self.collection.dataSource = self; self.collection.showsHorizontalScrollIndicator = NO;//滑條不出現 [self.collection registerClass:[CellOfFirst class] forCellWithReuseIdentifier:@"pool"];
<3>collectionView 的協議方法
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.marr.count;// 返回圖片的個數 } // 說一下爲何返回100個分區 // 咱們能夠將第50個分區的一組圖片做爲用戶看到的第一組圖片,這樣就實現輪播的效果了。(100分區足夠了,除非腦殘劃100次) - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 100; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { // 自定義的Cell類 CellOfFirst *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"pool" forIndexPath:indexPath]; cell.pic.image = self.marr[indexPath.row]; return cell; }
// 本地的圖片
- (void)createPhone { self.marr = [NSMutableArray array]; for (int i = 1; i < 12; i++) { NSString *name = [NSString stringWithFormat:@"123_%d.jpg",i]; UIImage *image = [UIImage imageNamed:name]; [self.marr addObject:image]; } //設置起始位置 [self.collection scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:50] atScrollPosition:UICollectionViewScrollPositionLeft animated:NO]; }
// 獲取pageControoler
// 被忘記調用呦 - (void)createPage { self.page = [[UIPageControl alloc]initWithFrame:CGRectMake(0, 250, WIDTH, 50)]; [self.view addSubview:self.page]; self.page.numberOfPages = self.marr.count; }
// 當圖片劃得時候已經減速時
// collectionView繼承於scrollview 因此咱們可用此方法 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { // 計算page算法 int page = (int) (scrollView.contentOffset.x / WIDTH + 0.5) % self.marr.count; self.page.currentPage = page; }
// 咱們能夠添加定時器了 (同樣別忘記獲取完圖片調用)
- (void)addTimer { self.timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; }
- (void)nextImage { //設置當前 indePath NSIndexPath *currrentIndexPath = [[self.collection indexPathsForVisibleItems]lastObject]; NSIndexPath *currentIndexPathReset = [NSIndexPath indexPathForItem:currrentIndexPath.item inSection:50]; [self.collection scrollToItemAtIndexPath:currentIndexPathReset atScrollPosition:UICollectionViewScrollPositionLeft animated:NO]; // 設置下一個滾動的item NSInteger nextItem = currentIndexPathReset.item +1; NSInteger nextSection = currentIndexPathReset.section; if (nextItem==self.marr.count) { // 當item等於輪播圖的總個數的時候 // item等於0, 分區加1 // 未達到的時候永遠在50分區中 nextItem=0; nextSection++; } NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection]; [self.collection scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES]; }
// 當用戶本身劃圖片時 固然咱們也須要定時器被移除 (時機很重要)
- (void)removeTimer{ [self.timer invalidate]; self.timer = nil; }
// 當圖片即將開始被拖拽時 咱們將定時器移除
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { [self removeTimer]; }
// 當圖片已經完成被拖拽時 咱們還需加上定時器
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { [self addTimer]; }
這些作完咱們基本就完成輪播圖自動輪播了,你們有興趣的能夠嘗試下。