標籤:
一.說明:
建立一個Single View Application,刪除main.stroryboard中原有的控制器,拖入一個新的CollectionViewController;
在原有的ViewController.h檔案中,將繼承改成UICollectionViewController,且綁定CollectionViewController
要使用原型cell來建立每張圖片,故建立相應的cell檔案並綁定.在原型cell中拖入一張imageView,並設定其約束覆蓋全cell
在Assets.xcassets中拖入圖片,至此基本介面搭建完畢.
二.實現代碼:
//// HBImageCell.h檔案// 4.30 圖片輪播#import <UIKit/UIKit.h>@interface HBImageCell : UICollectionViewCell//建立一個imgName屬性,當匯入imgName時,為映像賦值@property (nonatomic,copy)NSString *imgName;@end
設定cell中圖片的Outlets介面
//// HBImageCell.m檔案// 4.30 圖片輪播#import "HBImageCell.h"@interface HBImageCell ()@property (weak, nonatomic) IBOutlet UIImageView *imgView;@end@implementation HBImageCell-(void)setImgName:(NSString *)imgName{ _imgName = imgName; UIImage *img = [UIImage imageNamed:imgName]; self.imgView.image = img;}@end
/*
ViewController.m檔案中
思想:為了使圖片能無限輪播,將圖片每次的位置都滾動到第2位,且設立個新索引,圖片內容根據新索引變化 */#import "ViewController.h"#import "HBImageCell.h"//將圖片數量定義為宏,方便後期維護#define IMG_COUNT 9@interface ViewController ()//拖入layout的輸出介面@property (weak, nonatomic) IBOutlet UICollectionViewFlowLayout *flowLayout;@property (assign,nonatomic)int index;@end@implementation ViewController//在main.storyboard的cell中也應設定相同的可重用identifierstatic NSString *ID = @"IMG";#pragma mark - ViewDidLoad- (void)viewDidLoad { [super viewDidLoad]; //使每個儲存格的尺寸與螢幕相同 self.flowLayout.itemSize = self.view.frame.size; //設定儲存格之間的間隙為0 self.flowLayout.minimumLineSpacing = 0; //設定滾動方式為水平滾動 self.flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; //隱藏水平捲軸 self.collectionView.showsHorizontalScrollIndicator = NO; //設定分頁顯示 self.collectionView.pagingEnabled = YES; //剛開始就將其滾動到第2個位置 [self scrollToSecondPosition];}#pragma mark - 返回個數-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return IMG_COUNT;}#pragma mark - 返回內容-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ //取出原型cell HBImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath]; //要先判斷是向左拖還是向右拖,在拖動時就顯示圖片內容 //但不能直接在self.index上改動,否則在拖動結束後index還會自增(自減),故建立一個臨時變數 int tempIndex = self.index; if (indexPath.item == 0) { tempIndex --; }else if (indexPath.item == 2){ tempIndex ++; } //判斷越界 if (tempIndex == IMG_COUNT) { tempIndex = 0; }else if (tempIndex == -1){ tempIndex = IMG_COUNT - 1; } //為cell賦imgName NSString *imgName = [NSString stringWithFormat:@"%zd",tempIndex]; cell.imgName = imgName; return cell;}#pragma mark - 拖動結束時調用//通過該方法來確定圖片最後顯示的內容-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ //通過位移來得知是向左還是向右拖動 CGFloat offset = scrollView.contentOffset.x; int next = offset/self.flowLayout.itemSize.width; if (next == 0) { self.index--; }else if (next == 2){ self.index++; } //越界判斷 if (self.index == IMG_COUNT) { self.index = 0; }else if (self.index == -1){ self.index = IMG_COUNT - 1; } //加入非同步線程,回到第2個位置 dispatch_async(dispatch_get_main_queue(), ^{ [self scrollToSecondPosition]; }); }#pragma mark - 滾動到第二個的位置方法-(void)scrollToSecondPosition{ NSIndexPath *indexPath = [NSIndexPath indexPathForItem:1 inSection:0]; [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO]; }@end
至此實現程式碼完成.
三.最佳化
圖片的索引變化和判斷越界可使用一句最佳化演算法代替
/* ViewController.m檔案中 */-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ .... int tempIndex = self.index; if (indexPath.item == 0) { tempIndex --; }else if (indexPath.item == 2){ tempIndex ++; } //判斷越界 if (tempIndex == IMG_COUNT) { tempIndex = 0; }else if (tempIndex == -1){ tempIndex = IMG_COUNT - 1; } tempIndex = (tempIndex + (indexPath.item -1))%IMG_COUNT; ....}#pragma mark - 拖動結束時調用//通過該方法來確定圖片最後顯示的內容-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ //通過位移來得知是向左還是向右拖動 CGFloat offset = scrollView.contentOffset.x; int next = offset/self.flowLayout.itemSize.width; if (next == 0) { self.index--; }else if (next == 2){ self.index++; } //越界判斷 if (self.index == IMG_COUNT) { self.index = 0; }else if (self.index == -1){ self.index = IMG_COUNT - 1; } self.index = (self.index + (next - 1))%IMG_COUNT; ...}
四.注意點
HBImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
從原型cell中取得cell不需要註冊,而使用xib或class檔案中獲得cell則要在viewDidLoad中註冊相應的cell
//註冊nib [self.collectionView registerNib:<#(nullable UINib *)#> forCellWithReuseIdentifier:<#(nonnull NSString *)#>] //註冊class [self.collectionView registerClass:<#(nullable Class)#> forCellWithReuseIdentifier:<#(nonnull NSString *)#>]
CollectionView實現圖片無限切換