iOS無限輪播圖片的兩種方式

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。

初始狀態

  • 將試圖向左滑動後,屏幕上顯示的是R,即顯示的是圖片1。


則在此時,在後臺將M的圖片設置爲1,將UIScrollview的偏移量設置成初始狀態。接着將L設置爲0,R設置爲2。這裏的UIImageView的image變化和UIScrollView偏移量設置都不能開始UIView的動畫效果。最終的現實效果以下圖:

  • 向右滑動和向左滑動是同樣的道理,固然遇到array頭和尾時是須要處理的,使用模運算符(%)就能夠了:

    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];
}

這些作完咱們基本就完成輪播圖自動輪播了,你們有興趣的能夠嘗試下。

相關文章
相關標籤/搜索