單向輪播圖的簡單實現(xiàn)

說到輪播圖训裆,估計都不陌生钩骇,各種各樣的輪播圖在各個App上都不斷的被使用,因為輪播圖的界面簡潔并且內容涵蓋豐富郑象,所以經(jīng)常拿來進行使用贡这。但是無論輪播圖的樣式怎么變換,它的實現(xiàn)機制實際上都大同小異厂榛,今天就一點點說一下輪播圖的實現(xiàn)吧盖矫!

實現(xiàn)方案

實現(xiàn)這樣的界面實際上大家都有自己的想法,看到這樣的界面击奶,無疑會想到它的控件分布如下:

  1. 滾動視圖
  2. 每個滾動視圖的單元格圖片展示
  3. 滾動位置導航器(多種風格)

對應的結構圖如下所示:

cycleView.png

這不禁讓人想起了兩個控件來實現(xiàn)這樣的效果辈双,一個是UIScrollView,另外一個則是UICollectionView柜砾。這兩個都能實現(xiàn)滾動的效果湃望,因為UICollectionView繼承自UIScrollView,所以就以UIScrollView的實現(xiàn)方式來說起吧痰驱!

首先封裝這個控件之前证芭,我們需要兩個創(chuàng)建滾動視圖的變量,一個是數(shù)量bannerNum担映,以及另外一個變量輪播圖的圖片地址imageLink废士。這兩個變量在使用的時候需要傳遞給我們,然后才能依據(jù)這兩個變量創(chuàng)建相應的滾動視圖蝇完。結合這樣的邏輯官硝,我們可以將其設置為一個代理诅挑,然后使用的時候,通過代理將我們需要的變量傳遞進來也就滿足了創(chuàng)建需求泛源。
代理創(chuàng)建如下:

@protocol LCBannerScrollerViewDelegate <NSObject,UITableViewDelegate>

- (NSInteger )bannerView:(LCBannerScrollerView *)bannerScrollView;

- (NSString *)bannerLinks:(LCBannerScrollerView *)bannerScrollView linkForIndexOfBanner:(NSInteger)indexPath;

@optional
//相應廣告圖的點擊事件
- (void)bannerView:(LCBannerScrollerView *)bannerScrollView didClicked:(NSInteger)index;

@end

然后創(chuàng)建一個ScrollView滾動視圖拔妥,代碼如下:

- (void)creatView{
    
    //初始化數(shù)據(jù)
    self.index = 0;
    
    //從代理中獲取對應的滾動圖數(shù)量
    NSInteger bannerNum = [self.delegate bannerView:self];

    UIScrollView *banerScrollerView = [[UIScrollView alloc]init];
    banerScrollerView.frame = CGRectMake(0, 0,self.frame.size.width, self.frame.size.height-BarViewHeight);
    banerScrollerView.contentSize = CGSizeMake(self.frame.size.width * (bannerNum+2), 0);
    [self addSubview:banerScrollerView];
    self.bannerScrollView = banerScrollerView;
    
    banerScrollerView.pagingEnabled = YES;
    banerScrollerView.bounces = NO;
    banerScrollerView.delegate = self;
    banerScrollerView.scrollsToTop = NO;
    banerScrollerView.showsHorizontalScrollIndicator = NO;
    
    //創(chuàng)建廣告圖
    CGFloat img_x = 0;
    CGFloat img_y = 0;
    CGFloat img_w = SCREEN_WIDTH;
    CGFloat img_h = self.frame.size.height - BarViewHeight;
    
    for (int i = 0; i<bannerNum; i++) {
        
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(img_x, img_y, img_w, img_h);
        [button addTarget:self action:@selector(bannerTouch:) forControlEvents:UIControlEventTouchUpInside];
        NSString *imageLink = [self.delegate bannerLinks:self linkForIndexOfBanner:i];
        
        [button sd_setBackgroundImageWithURL:[NSURL URLWithString:imageLink] forState:UIControlStateNormal placeholderImage:[UIImage imageNamed:@"placeholder3"]];
        button.contentMode = UIViewContentModeCenter;
        
        button.tag = i;
        [banerScrollerView addSubview:button];
        [self.bannerViewArray addObject:button];
        
        img_x += img_w;
    }
    
    //創(chuàng)建導航pageController(該項目為底部滑塊滾動條)
    CGFloat bar_x = 0;
    CGFloat bar_y = img_h;
    CGFloat bar_w = self.frame.size.width/bannerNum;
    CGFloat bar_h = BarViewHeight;
    
    for (int i=0; i<bannerNum; i++) {
        
        UIView *barView = [[UIView alloc]init];
        barView.frame = CGRectMake(bar_x, bar_y, bar_w, bar_h);

        barView.tag = i;
        [self addSubview:barView];
        [self.bottomViewArray addObject:barView];
        
        bar_x += bar_w;
    }
    
    //添加滑塊游標
    UIView *actionView = [[UIView alloc]init];
    if (self.bottomViewArray.count) {
        UIView *firstBarView = self.bottomViewArray[0];
        actionView.frame = firstBarView.frame;
        actionView.backgroundColor = _barViewColor ? _barViewColor : barViewColor;
        self.actionBarView = actionView;
        [self addSubview:_actionBarView];
    }
    
    
}

/*
** 將滾動圖的點擊事件傳遞給代理,將點擊事件通過代理來進行回調
*/
- (void)bannerTouch:(UIButton*)button{

    [self.delegate bannerView:self didClicked:button.tag];
    
}


寫完以上代碼达箍,實際上輪播圖的模樣已經(jīng)清晰了没龙,但是輪播圖不能自動滾動,只能拿手進行拖動缎玫。實現(xiàn)自動滾動需要一個定時器來進行循環(huán)的操作硬纤,我們創(chuàng)建一個定時器:

// 釋放時取消定時器
- (void)dealloc {
    [self.timer invalidate];
}

//懶加載
- (NSTimer *)timer {
    if (!_timer) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:AnimotionTime target:self selector:@selector(scrollBanner:) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
    }
    
    return _timer;
}


有時候為了讓自動滾動變得靈活可控,通常啟動定時器的方法將其設定為對外接口赃磨,通過由外界來控制定時器的啟動筝家。自動滾動開始以后,我們貌似忽略了一個重點內容邻辉,就是滾動導航指示器(通常為UIPageController)的指示溪王,這個滾動的指示我們可以通過UIScrollView的代理中回調的偏移量進行計算得出當前頁。具體如下:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    
    CGFloat offset_x = scrollView.contentOffset.x;
    self.index = offset_x/scrollView.frame.size.width;
    
    
    //實時改變底部滑塊的位置
    CGFloat offsetX_zoom = (offset_x - SCREEN_WIDTH * self.index) / SCREEN_WIDTH;
    UIView *currentView = self.bottomViewArray[self.index];
        
    CGRect frame = currentView.frame;
    frame.origin.x += offsetX_zoom * (SCREEN_WIDTH/self.bottomViewArray.count);
    self.actionBarView.frame = frame;
    
}


- (void)scrollBanner:(NSTimer *)timer{
    
    CGFloat offset_x = 0;
    CGFloat offset_y = 0;
    
    offset_x = _index * self.frame.size.width;
        
    //讓滾動平滑緩慢
    offset_x = _index * self.frame.size.width;
    [UIView animateWithDuration:ScrollTime delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
            [self.bannerScrollView setContentOffset:CGPointMake(offset_x, offset_y) animated:NO];
        } completion:nil];    

    _index ++;
     
}

滾動完成以后值骇,我們可能會遇到一個問題莹菱,那就是用手滾動滾動圖的時候,會發(fā)現(xiàn)手勢不能停止自動滾動吱瘩,顯然這樣的結果不是我們想要的道伟,為了解決這個問題,我們在手勢觸發(fā)滾動的時候暫停計時器的及時使碾,等手勢移除之后再將定時器恢復就可以解決問題了蜜徽。解決如下:

//手勢開始觸發(fā)
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{

    [self endSchedulTime];
}

//手勢結束觸發(fā)
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    //恢復定時器計時
    [self startSchedulTime];
    
}

- (void)endSchedulTime{
    // 停止計時
    [self.timer setFireDate:[NSDate distantFuture]];
}

- (void)startSchedulTime{
    // 開始計時(手勢停止后,要延遲一段時間再進行滾動票摇,否則手勢一旦停止就立即滾動會顯得滾動倉促拘鞋,這個時間根據(jù)需求來定)
    [self.timer setFireDate:[NSDate dateWithTimeInterval:1.5 sinceDate:[NSDate date]]];

}


好了,簡單的輪播圖就這樣實現(xiàn)了兄朋,是不是很簡單呢掐禁!效果如下:

滾動視圖.gif

至于無限輪播圖,就等到下一篇在進行詳細的介紹吧颅和!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末傅事,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子峡扩,更是在濱河造成了極大的恐慌蹭越,老刑警劉巖鞋拟,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妇斤,死亡現(xiàn)場離奇詭異署驻,居然都是意外死亡乎串,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門买置,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粪糙,“玉大人,你說我怎么就攤上這事忿项∪馗裕” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵轩触,是天一觀的道長寞酿。 經(jīng)常有香客問我,道長脱柱,這世上最難降的妖魔是什么伐弹? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮榨为,結果婚禮上惨好,老公的妹妹穿的比我還像新娘。我一直安慰自己柠逞,他們只是感情好昧狮,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布景馁。 她就那樣靜靜地躺著板壮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪合住。 梳的紋絲不亂的頭發(fā)上绰精,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機與錄音透葛,去河邊找鬼笨使。 笑死,一個胖子當著我的面吹牛僚害,可吹牛的內容都是我干的硫椰。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼萨蚕,長吁一口氣:“原來是場噩夢啊……” “哼靶草!你這毒婦竟也來了?” 一聲冷哼從身側響起岳遥,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤奕翔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后浩蓉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體派继,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡宾袜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了驾窟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庆猫。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖绅络,靈堂內的尸體忽然破棺而出阅悍,到底是詐尸還是另有隱情,我是刑警寧澤昨稼,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布节视,位于F島的核電站,受9級特大地震影響假栓,放射性物質發(fā)生泄漏寻行。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一匾荆、第九天 我趴在偏房一處隱蔽的房頂上張望拌蜘。 院中可真熱鬧,春花似錦牙丽、人聲如沸简卧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽举娩。三九已至,卻和暖如春构罗,著一層夾襖步出監(jiān)牢的瞬間铜涉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工遂唧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留芙代,地道東北人。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓盖彭,卻偏偏與公主長得像纹烹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子召边,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內容

  • 內容抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新...
    皇小弟閱讀 46,791評論 22 665
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫铺呵、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,124評論 4 61
  • 許峻閱讀 75評論 0 0
  • 1掌实、要環(huán)境來適應我們陪蜻,還是自己去適應環(huán)境 我想起一個故事,大概是這樣 一位富商生了一場大病贱鼻,住院康復后宴卖,醫(yī)生叮囑他...
    晴天有小雨Eason閱讀 188評論 0 1
  • 我長那么大滋将,從來都沒有覺得自己會如此一無是處,直到遇到你症昏,哪怕與你分開至今随闽,不斷感覺到自卑不斷感覺到自己真的一無是...
    旖睿睿閱讀 240評論 0 0