iOS ScrollView 的重用

支持的功能:

  1. 無限輪播
  2. 定時器輪播
  3. 重用

原理:利用3(0 1 2)個視圖不斷的切換正驻,滑動結(jié)束的時候始終讓1顯示在屏幕中間。
詳情請看方法[self reloadImage];

.h

#import <UIKit/UIKit.h>
typedef void (^ImageViewClick)(NSInteger index);
@interface JAScrollView : UIView
@property (nonatomic,assign)BOOL isRunloop;//是否開啟定時器 default NO
@property (nonatomic,assign)NSTimeInterval dur; //default 3
@property (nonatomic,strong)UIColor *color_pageControl;
@property (nonatomic,strong)UIColor *color_currentPageControl;
@property (nonatomic,strong)ImageViewClick click;
- (instancetype)initWithFrame:(CGRect)frame
                   withImages:(NSArray *)images
                withIsRunloop:(BOOL)isRunloop
                    withBlock:(ImageViewClick)block;

@end

.m

//
//  JAScrollView.m
//  AutomobileAccessories
//
//  Created by JA on 2017/3/17.
//  Copyright ? 2017年  All rights reserved.
//

#import "JAScrollView.h"
#import "BaseDefine.h"
typedef enum : NSUInteger {
    ScrollViewDirectionRight,           /** 向右滾動*/
    ScrollViewDirectionLeft,            /** 向左滾動*/
}ScrollViewDirection;
@interface JAScrollView() <UIScrollViewDelegate>

@property (nonatomic,strong)UIScrollView *scrollView;
@property (nonatomic,strong)NSArray *dataArry;
@property (nonatomic,assign)NSInteger currentImageIndex;
@property (nonatomic,assign)CGFloat lastContentOffset;
@property (nonatomic,assign)ScrollViewDirection scrollDirection;
@property (nonatomic,strong)NSMutableArray *imageViews;
@property (nonatomic,assign)NSInteger imageCount;
@property (nonatomic,strong)NSTimer *timer;
@property (nonatomic,strong)UIPageControl *pageControl;
@end
@implementation JAScrollView
@synthesize color_currentPageControl = _color_currentPageControl ,
color_pageControl = _color_pageControl ;
- (instancetype)initWithFrame:(CGRect)frame
                   withImages:(NSArray *)images
                withIsRunloop:(BOOL)isRunloop
                    withBlock:(ImageViewClick)block;
{
   self = [super initWithFrame:frame];
    if (self) {
        self.dur = 3;
        self.imageCount = images ? images.count : 0;
        self.isRunloop = isRunloop;
        self.dataArry = images;
        self.click = block;
        [self loadBaseView];
    }
    return self;
}
- (void)loadBaseView
{
  
    self.currentImageIndex =0;
    self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width, 0);
    for (int i = 0; i<3; i ++) {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(i*self.scrollView.frame.size.width, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
       
        if (i == 0 && self.dataArry!=nil && self.dataArry.count > 1) {
            imageView.backgroundColor = self.dataArry[self.dataArry.count - 1];//左邊
        }
        if (i == 1 && self.dataArry!=nil && self.dataArry.count > 0) {
            imageView.backgroundColor = self.dataArry[0];//中間
        }
        if (i == 2 && self.dataArry !=nil && self.dataArry.count > 1) {
            imageView.backgroundColor = self.dataArry[1];//右邊
        }
        [self.imageViews addObject:imageView];
        [self.scrollView addSubview:imageView];
        
    }
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
    [self.scrollView addGestureRecognizer:tap];
    [self addSubview:self.scrollView];
    [self addSubview:self.pageControl];
       
    
}

#pragma mark -
#pragma mark - set
- (void)setImageCount:(NSInteger)imageCount
{
    _imageCount = imageCount;
    if (_imageCount < 1) {
        self.scrollView.scrollEnabled = NO;
        return;
    }
    self.scrollView.scrollEnabled = YES;
    self.pageControl.numberOfPages = imageCount ;
    CGSize size = [self.pageControl sizeForNumberOfPages:imageCount];
    self.pageControl.bounds = CGRectMake(0, 0, size.width, size.height);
    self.pageControl.center = CGPointMake(self.frame.size.width - size.width - 0. , self.frame.size.height - 20.) ;
    self.pageControl.currentPage = 0;
}
- (void)setIsRunloop:(BOOL)isRunloop
{
    _isRunloop = isRunloop;
    if (isRunloop) {
        [self createTimer];
    }
}
- (void)setColor_pageControl:(UIColor *)color_pageControl
{
    _color_pageControl = color_pageControl ;
    
    self.pageControl.pageIndicatorTintColor = _color_pageControl ;
}
//default whiteColor
- (UIColor *)color_pageControl
{
    if (!_color_pageControl) {
        _color_pageControl = [UIColor whiteColor] ;
    }
    return _color_pageControl ;
}

- (void)setColor_currentPageControl:(UIColor *)color_currentPageControl
{
    _color_currentPageControl = color_currentPageControl ;
    
    self.pageControl.currentPageIndicatorTintColor = _color_currentPageControl ;
}
//default darkGrayColor
- (UIColor *)color_currentPageControl
{
    if (!_color_currentPageControl) {
        _color_currentPageControl = [UIColor darkGrayColor] ;
    }
    return _color_currentPageControl ;
}
//create timer
- (void)createTimer{
    if (self.timer == nil) {
        self.timer = [NSTimer scheduledTimerWithTimeInterval:self.dur target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
         [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    }
}
#pragma mark -
#pragma mark - action
- (void)timerAction{
    if (_imageCount <= 1) return ;
    [self.scrollView setContentOffset:CGPointMake(self.scrollView.frame.size.width *2, 0) animated:YES];
    [self performSelector:@selector(reloadImage) withObject:nil afterDelay:.35];

}
- (void)tapAction{
    if (self.click) {
        self.click(_currentImageIndex);
    }
}
#pragma mark -
#pragma mark - scrollViewDelegate

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self reloadImage];
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    //    NSLog(@"開始拖拽");
        [self.timer invalidate];
        self.timer = nil;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    [self createTimer];
}
- (void)reloadImage
{
    if ( self.imageViews.count == 0 || self.dataArry.count == 0) {
        return;
    }
    NSInteger leftImageIndex,rightImageIndex ;
    CGPoint offset = [_scrollView contentOffset] ;
    
    if (offset.x > self.frame.size.width)
    { //  向右滑動
        _currentImageIndex = (_currentImageIndex + 1) % self.dataArry.count ;
    }
    else if(offset.x < self.frame.size.width)
    { //  向左滑動
        _currentImageIndex = (_currentImageIndex + self.dataArry.count - 1) % self.dataArry.count ;
    }
    
    UIImageView * centerImageView = [self.imageViews objectAtIndex:1];
    UIImageView *leftImageView = [self.imageViews objectAtIndex:0];
    UIImageView *rightImageView = [self.imageViews objectAtIndex:2];
    
    centerImageView.backgroundColor =self.dataArry[_currentImageIndex];
    
    //  重新設(shè)置左右圖片
    leftImageIndex  = (_currentImageIndex + self.dataArry.count - 1) % self.dataArry.count ;
    rightImageIndex = (_currentImageIndex + 1) % self.dataArry.count ;
    leftImageView.backgroundColor  = self.dataArry[leftImageIndex] ;
    rightImageView.backgroundColor = self.dataArry[rightImageIndex] ;
    
    [self.scrollView setContentOffset:CGPointMake(self.scrollView.frame.size.width, 0) animated:NO];
    self.pageControl.currentPage = self.currentImageIndex;
}

#pragma mark -
#pragma mark -懶加載
- (NSMutableArray *)imageViews
{
    if (!_imageViews) {
        _imageViews = [[NSMutableArray alloc] init];
    }
    return _imageViews;
}
- (UIScrollView *)scrollView
{
    if (!_scrollView) {
        _scrollView = [[UIScrollView alloc] init];
        _scrollView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
        _scrollView.contentSize = CGSizeMake(self.frame.size.width *3, self.frame.size.height);
        _scrollView.delegate = self;
        _scrollView.pagingEnabled = YES;
        _scrollView.showsVerticalScrollIndicator = NO;
        _scrollView.showsHorizontalScrollIndicator = NO;
        _scrollView.bounces = NO;
    
    }
    return _scrollView;
}
- (UIPageControl *)pageControl
{
    if (!_pageControl) {
        _pageControl = [[UIPageControl alloc] init] ;
        _pageControl.pageIndicatorTintColor = self.color_pageControl ;
        _pageControl.currentPageIndicatorTintColor = self.color_currentPageControl ;
        
    }
    
    return _pageControl ;
}
- (void)dealloc
{
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
    
}
@end

使用方法:

//數(shù)組傳字符串會crash锌钮,可以自行修改告希!
  NSMutableArray *images = [NSMutableArray arrayWithCapacity:0];
    for (int i = 0; i < 1000; i ++) {

        [images addObject:[UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1.0]];
    }
    JAScrollView *scroll = [[JAScrollView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_W, H) withImages:images withIsRunloop:YES withBlock:^(NSInteger index){
        NSLog(@"當前點擊了index:%zd",index);
    }];

demo下載地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扑浸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子燕偶,更是在濱河造成了極大的恐慌喝噪,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件指么,死亡現(xiàn)場離奇詭異酝惧,居然都是意外死亡,警方通過查閱死者的電腦和手機伯诬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門晚唇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盗似,你說我怎么就攤上這事哩陕。” “怎么了赫舒?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵悍及,是天一觀的道長。 經(jīng)常有香客問我号阿,道長并鸵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任扔涧,我火速辦了婚禮园担,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘枯夜。我一直安慰自己弯汰,他們只是感情好,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布湖雹。 她就那樣靜靜地躺著咏闪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摔吏。 梳的紋絲不亂的頭發(fā)上鸽嫂,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音征讲,去河邊找鬼据某。 笑死,一個胖子當著我的面吹牛诗箍,可吹牛的內(nèi)容都是我干的癣籽。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼筷狼!你這毒婦竟也來了瓶籽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤埂材,失蹤者是張志新(化名)和其女友劉穎塑顺,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體楞遏,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡茬暇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了寡喝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡勒奇,死狀恐怖预鬓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赊颠,我是刑警寧澤格二,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站竣蹦,受9級特大地震影響顶猜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜痘括,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一长窄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纲菌,春花似錦挠日、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至椅贱,卻和暖如春懂算,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庇麦。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工计技, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人女器。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓酸役,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子涣澡,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,841評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫贱呐、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,066評論 4 62
  • 因為鴿子什么都不用擔(dān)心入桂,什么都不用考慮奄薇,它從不迷戀某一片陸地,就連枝頭也像鉸鏈那樣栓住了它
    十一爸爸閱讀 185評論 0 0
  • 臨摹書上的食物抗愁,hb鉛筆馁蒂。
    山水奏鳴閱讀 314評論 1 3