无限循环的ScrollView,原理以及实现,自动循环!!!

逑兴安
2023-12-01

本人~菜鸟一枚,这两天闲着无聊,就寻思自己写一下ScrollView自动无限循环,借鉴了不少别人写的,但发现还都不是很全面,自己整合一下,以备初学者们参观研习,废话不多说,直接上代。

首先是.h

@protocol ImageScrollViewDelegate <NSObject>

//@required //必须不必须看你自己了。

-(void)didSelectImageAtIndex:(NSInteger)index;//代理事件,需要把点击是哪个图片传出来。

@end

@interface ImageScrollView : UIView

@property(nonatomic, assign) id<ImageScrollViewDelegate> delegate;

-(ImageScrollView *)initWithFrame:(CGRect)frame ImageArray:(NSArray *)imgArr;//这个是初始化方法应该都可以看懂的!

@end

接下来是.m

#define  screen_width [UIScreen mainScreen].bounds.size.width   //自己定义的宏 ,屏幕宽度。

#define  scren_Height [UIScreen mainScreen].bounds.size.height  //屏幕高度。

@interface ImageScrollView ()<UIScrollViewDelegate>

{   //声明了几个需要的控件,这个不需要暴露在外面,所以写在.m里,别问我为什么不用属性,我就是看着好看,用着舒服。

    CGRect scrollFrame;

    NSTimer *_timer;//定时器,自动播放时候要用到。

    NSInteger totalPage; //总共的页数。

    NSInteger curPage;// 当前的page。

    UIScrollView *mainScrollView;

    UIPageControl *pageControl;

}


@property(nonatomic,strong) NSMutableArray *curImageArray;

@property(nonatomic, strong) NSArray *imgArray;

@end


@implementation ImageScrollView


-(ImageScrollView *)initWithFrame:(CGRect)frame ImageArray:(NSArray *)imgArr{

    self = [super initWithFrame:frame];

    if (self) {

        //创建scrollview

        scrollFrame = frame;

        totalPage = imgArr.count;

        curPage = 2;

        self.curImageArray = [[NSMutableArray alloc]init];

        self.imgArray = [NSArray arrayWithArray:imgArr];

        mainScrollView = [[UIScrollView alloc] initWithFrame:frame];

        mainScrollView.contentSize = CGSizeMake(3*screen_width, frame.size.height);

        mainScrollView.pagingEnabled = YES;

        mainScrollView.delegate = self;

        mainScrollView.showsHorizontalScrollIndicator = NO;

        [self addSubview:mainScrollView];

       

        pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(screen_width/2-40, frame.size.height-40, 80, 30)];

        pageControl.numberOfPages = 5;

        [self addSubview:pageControl];

        

        [self refreshScrollView];

        

        [self addTimer];

    }

    return self;

}

-(void)refreshScrollView;//这个是刷新重铺ImageView

{

    NSArray *subviews = [mainScrollView subviews];

    if (subviews.count != 0) {

        [subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

    }//删除mainScrollView上的所有ImageView,也就3个。

    [self getDisplayImagesWithCurpage:curPage];

    //添加图片

    for(int i = 0; i < 3; i++){//只创建3个imageview

        UIImageView *imageView = [[UIImageView alloc] init];

        imageView.frame = CGRectOffset(scrollFrame, screen_width *i, 0);

        [imageView setImage:[UIImage imageNamed:[self.curImageArray objectAtIndex:i]]];

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(OnTapImage:)];//添加点击时间哦。

        [imageView addGestureRecognizer:tap];

        imageView.userInteractionEnabled = YES;

        [mainScrollView addSubview:imageView];

        UILabel *label  = [[UILabel alloc]init];

        label.frame = CGRectOffset(CGRectMake(10, 10, 50, 50), screen_width *i, 0);

        label.font = [UIFont systemFontOfSize:20];

        label.text = [self.curImageArray objectAtIndex:i];

        label.textColor = [UIColor redColor];

        label.textAlignment = 1;

        [mainScrollView addSubview:label];

    }

       [mainScrollView setContentOffset:CGPointMake(scrollFrame.size.width, 0)];//重铺页面之后要神不知鬼不觉的滚动到第二个imageview,注意scrollFrame.size.width,也就是第二个屏幕宽度的位置

  

}

- (void)getDisplayImagesWithCurpage:(NSInteger)page//这个方法是取到当前页面的上一个图片和下一个图片一起加到curImageArray中

{

    NSInteger prePage = [self validPageValue:(page-1)];

    NSInteger lastOage = [self validPageValue:(page+1)];

    if (self.curImageArray.count != 0) {

        [self.curImageArray removeAllObjects];

        

    }

    [self.curImageArray addObject:[self.imgArray objectAtIndex:(prePage-1)]];

    [self.curImageArray addObject:[self.imgArray objectAtIndex:(page-1)]];

    [self.curImageArray addObject:[self.imgArray objectAtIndex:(lastOage-1)]];

}

- (NSInteger)validPageValue:(NSInteger)value//这个方法是判定不能超出总数,详细自己看吧

{

    if (value == 0) {

        value = totalPage;

    }

    

    if (value == totalPage+1) {

        value = 1;

    }

    return value;

}

-(void)OnTapImage:(UITapGestureRecognizer *)sender{

    [self.delegate didSelectImageAtIndex:curPage];

}


-(void)addTimer{//这个是添加定时器,为什么要用到RunLoop呢?因为是为了防止如果你把这个view放在另一个Scrollview中时,例如做tabview的cell时,滑动cell,图片就不自动滚动了

    _timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(netxPage) userInfo:nil repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];

}


-(void)removeTimer{//注销定时器

    [_timer invalidate];

}

-(void)netxPage{//这个是定时器调用的方法,这让它自动滚到下一个imageview就可以,mainScrollView.contentOffset.x+screen_width,他滚动的时候会自己掉用代理方法-(void)scrollViewDidScroll:(UIScrollView *)scrollView的,其他不用管。

    [mainScrollView setContentOffset:CGPointMake(mainScrollView.contentOffset.x+screen_width,0) animated:YES];

}


#pragma mark - UIScrollViewDelegate

//滑动时

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

    pageControl.currentPage = curPage-1;

    int x = scrollView.contentOffset.x;

    if (x >= scrollFrame.size.width *2) {

        curPage = [self validPageValue:(curPage+1)];

        [self refreshScrollView];

    }

    if(x <= 0) {

        curPage = [self validPageValue:curPage-1];

        [self refreshScrollView];

    }

    

}

//开始拖动时,移除timer

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{//手指拖动的时候要移除timer,否则会混乱的哦。自己实验!!

    [self removeTimer];

}

//结束拖动,添加timer

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{//结束触摸的时候要把timer加回来

    [self addTimer];

}


-(void)dealloc{

    [self removeTimer];

}

好了就这么多!!自己看一下应该就能看懂,源码我就不传了,直接把这个复制到项目里,应该就可以用,初学者一定要自己多敲几遍,练习练习!!!!
 类似资料: