圖片輪播器:
一、實現效果
實現圖片的自動輪播

二、實現代碼
storyboard中布局

代碼:
1 #import "YYViewController.h" 2 3 @interface YYViewController () <UIScrollViewDelegate> 4 @property (weak, nonatomic) IBOutlet UIScrollView *scrollview; 5 /** 6 * 頁碼 7 */ 8 @property (weak, nonatomic) IBOutlet UIPageControl *pageControl; 9 10 @property (nonatomic, strong) NSTimer *timer; 11 @end 12 13 @implementation YYViewController 14 15 - (void)viewDidLoad 16 { 17 [super viewDidLoad]; 18 19 // 圖片的寬 20 CGFloat imageW = self.scrollview.frame.size.width; 21 // CGFloat imageW = 300; 22 // 圖片高 23 CGFloat imageH = self.scrollview.frame.size.height; 24 // 圖片的Y 25 CGFloat imageY = 0; 26 // 圖片中數 27 NSInteger totalCount = 5; 28 // 1.添加5張圖片 29 for (int i = 0; i < totalCount; i++) { 30 UIImageView *imageView = [[UIImageView alloc] init]; 31 // 圖片X 32 CGFloat imageX = i * imageW; 33 // 設置frame 34 imageView.frame = CGRectMake(imageX, imageY, imageW, imageH); 35 // 設置圖片 36 NSString *name = [NSString stringWithFormat:@"img_0%d", i + 1]; 37 imageView.image = [UIImage imageNamed:name]; 38 // 隱藏指示條 39 self.scrollview.showsHorizontalScrollIndicator = NO; 40 41 [self.scrollview addSubview:imageView]; 42 } 43 44 // 2.設置scrollview的滾動范圍 45 CGFloat contentW = totalCount *imageW; 46 //不允許在垂直方向上進行滾動 47 self.scrollview.contentSize = CGSizeMake(contentW, 0); 48 49 // 3.設置分頁 50 self.scrollview.pagingEnabled = YES; 51 52 // 4.監聽scrollview的滾動 53 self.scrollview.delegate = self; 54 55 [self addTimer]; 56 } 57 58 - (void)nextImage 59 { 60 int page = (int)self.pageControl.currentPage; 61 if (page == 4) { 62 page = 0; 63 }else 64 { 65 page++; 66 } 67 68 // 滾動scrollview 69 CGFloat x = page * self.scrollview.frame.size.width; 70 self.scrollview.contentOffset = CGPointMake(x, 0); 71 } 72 73 // scrollview滾動的時候調用 74 - (void)scrollViewDidScroll:(UIScrollView *)scrollView 75 { 76 NSLog(@"滾動中"); 77 // 計算頁碼 78 // 頁碼 = (contentoffset.x + scrollView一半寬度)/scrollView寬度 79 CGFloat scrollviewW = scrollView.frame.size.width; 80 CGFloat x = scrollView.contentOffset.x; 81 int page = (x + scrollviewW / 2) / scrollviewW; 82 self.pageControl.currentPage = page; 83 } 84 85 // 開始拖拽的時候調用 86 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView 87 { 88 // 關閉定時器(注意點; 定時器一旦被關閉,無法再開啟) 89 // [self.timer invalidate]; 90 [self removeTimer]; 91 } 92 93 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 94 { 95 // 開啟定時器 96 [self addTimer]; 97 } 98 99 /** 100 * 開啟定時器 101 */ 102 - (void)addTimer{ 103 104 self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(nextImage) userInfo:nil repeats:YES]; 105 106 } 107 /** 108 * 關閉定時器 109 */ 110 - (void)removeTimer 111 { 112 [self.timer invalidate]; 113 } 114 @end
提示:以下兩個屬性已經和storyboard中的控件進行了連線。
@property (weak, nonatomic) IBOutletUIScrollView *scrollview;
@property (weak, nonatomic) IBOutletUIPageControl *pageControl;
補充:定時器NSTimer
定時器 適合用來隔一段時間做一些間隔比較長的操作
NSTimeInterval:多長多件操作一次
target :操作誰
selector : 要操作的方法
userInfo: 傳遞參數
repeats: 是否重復
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
-------------------------------------------------------------------
無線循環效果:
平時APP中的廣告位、或者滾動的新聞圖片等用到的就是圖片輪播這種效果,實現方式主要有兩種,一種是ScrollView+ImageView,另一種則是通過CollectionView,今天總結的是ScrollView這種方式。
1.圖片輪播效果實現
主要實現思路是:根據圖片總數及寬高設置好ScrollView的大小,每切換一張圖片相當於在ScrollView上進行一個圖片寬度的移動行為,並加入定時器,實現自動輪播。
如圖所示,設置好ScrollView及PageControl,ScrollView的contentSize根據圖片數量確定,注意啟用pagingEnabled這個屬性,確保整頁移動,同樣pageControl也是根據圖片數量來確定,每一頁代表一張圖片。

圖片命名采用數字序號方式,方便使用,需要注意的是,pageControl是由0開始的,也就是0對應image1,1對應image2...依次類推


加載圖片並將准備好的圖片在ScrollView里設置好位置,即將這些圖片一張緊挨着一張排列在ScrollView中。

通過ScrollView的代理方法,在ScrollView滾動結束的時候根據 contentOffset 更新頁碼。

定時器設置,這里設置為每隔2秒滾動更新一次,實際上就是每隔2秒更新一次頁碼,根據頁碼的變化,讓ScrollView跟着移動,每次移動一張圖片的距離

這里還需要注意的是,由於加入定時器有自動輪播的效果了,會與手動拖拽ScrollView沖突,即手動拖拽ScrollView過程中可能 ScrollView可能自動移動更新圖片了,顯然這種效果是不符合用戶習慣的,這時需要在ScrollView的代理事件中進行處理,即開始拖拽 ScrollView時停止定時器,拖拽結束后再開啟定時器。

那到這里是不是就結束了呢?我們看看效果圖:

這里有兩個問題:
(1)首先是移動到最后一張圖片時無法移動了,如果是制作APP的新特性頁面,這樣的滾動效果已經可以了,但如果在廣告位或者是滾動新聞這些場景下這種效果是不夠好的,一般滾動到最后一張圖片時,繼續拖拽都會移動到第一張圖片,實現一種滾動循環效果。
(2)定時器自動輪播圖片時,確實圖片循環輪播了,但是仔細看會發現,ScrollView是由最后一種圖片位置生硬得拉回到第一張圖片的位置,效果也不夠理想。
解決辦法下面接着說。
2.圖片輪播無限循環效果實現
剛剛說到第一個問題,ScrollView移動到最后一張圖片時無法移動了,這是因為ScrollView已經移動到最后,而圖片又是依次排列,自然也就無法移動。
解決辦法是,我們換一個思路實現圖片輪播效果,ScrollView上只放三個ImageView,屏幕始終顯示中間的ImageView,左邊 和右邊的ImageView分別代表前一張圖片和后一張圖片,屏幕移動的時候,中間的ImageView變化,同時左右兩邊的ImageView也隨之變 化,兩種邊界情況:
(1)當屏幕顯示最后一張圖片時,右邊的ImageView也也即下一站圖片應該是最開始的第一張圖片;
(2)當屏幕顯示最開始的第一張圖片時,左邊的ImageView也即上一張圖片應該是最后一張圖片。
這樣三個ImageView不斷變化就造成一種圖片輪播無限循環的效果。 參考: http://www.cnblogs.com/kenshincui/p/3913885.html
相對於之前的效果,有一些改變,主要有:
(1)ScrollView只需要設置三個ImageView即可,並且默認顯示中間的ImageView

(2)根據ScrollView的移動情況,迅速變化三個ImageView中圖片數據

(3)ImageView更新完畢后,偷偷把ScrollView拉回到中間的ImageView位置,這樣視覺效果上就實現了無限循環的效果

效果圖:

但是,這里在加入定時器后實現圖片輪播自動循環時遇到了問題,主要是初始化顯示第一張圖片與根據定時器設置自動移動ScrollView有一些沖突,在code4App上找到其他人一個工程,采用的思路相同,單獨封裝了ScrollView進行處理,已經解決該問題。
可參考:http://code4app.com/ios/AdScrollerView/54955a78933bf0f2168b45b4
圖片輪播器參考自:http://www.cnblogs.com/wendingding/p/3763527.html
無限循環效果參考自:http://www.tuicool.com/articles/reu22eu
額外補充:
動態修改UIPageControll的頁碼有兩種方式:
1.實時計算
- (void)scrollViewDidScroll:(nonnull UIScrollView *)scrollView { // 1.計算頁碼 // 當前頁碼 = 偏移位 / UIScrollView的寬度 CGFloat page = scrollView.contentOffset.x / scrollView.frame.size.width; int currnetPage = page + 0.5; // 2.修改頁碼 self.pageControl.currentPage = currnetPage; }
2.拖拽完畢計算
// + 2.1停止拖拽 - (void)scrollViewDidEndDragging:(nonnull UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { if (decelerate == NO) { [self scrollViewDidEndDecelerating:scrollView]; } } // + 2.2停止減速 - (void)scrollViewDidEndDecelerating:(nonnull UIScrollView *)scrollView { // 1.計算頁碼 // 當前頁碼 = 偏移位 / UIScrollView的寬度 int page = scrollView.contentOffset.x / scrollView.frame.size.width; NSLog(@"page = %i", page); // 2.修改頁碼 self.pageControl.currentPage = page; }

