UIScrollView配合定时器和手动实现图片轮播无限循环

时间:2021-01-18 00:10:25

研究了两天半时间,新手无奈啊,话不多说,直接上代码。

#import "TestViewController.h"


#define s_x [UIScreen mainScreen].bounds.size.width

#define s_y [UIScreen mainScreen].bounds.size.height

NSArray * imagearr;

NSTimer * timer;

int _currentImageIndex;

@interface TestViewController ()<UIScrollViewDelegate>

@property (nonatomic,retain)UIScrollView * scv;

@property (nonatomic,retain)UIPageControl * page;

@property (nonatomic,retain)UIImageView * leftimageview;

@property (nonatomic,retain)UIImageView * centerimageview;

@property (nonatomic,retain)UIImageView * rightimageview;


@end


@implementation TestViewController


- (void)viewDidLoad {

    [superviewDidLoad];

    // Do any additional setup after loading the view.

    self.view.backgroundColor=[UIColorwhiteColor];

    imagearr=@[@"0.jpg",@"1.jpg",@"2.jpg",@"3.jpg",@"4.jpg",@"5.jpg"];


    [selfmainView];

    

    [selfsetimageview];

    

    [selfsetDefaultImage];

    

    [selfsettimer];

    

}

-(void)settimer{

    timer=[NSTimerscheduledTimerWithTimeInterval:3target:selfselector:@selector(timechanged)userInfo:nilrepeats:YES];

    NSLog(@"定时器启动");

    [[NSRunLoopcurrentRunLoop]addTimer:timerforMode:NSRunLoopCommonModes];

}

-(void)timechanged{

    int leftimageindex,rightimageindex;

    CGPoint offset=[_scvcontentOffset];//内容视图的位置

    //滑动发生后,实时变化图片加载,所以最先考虑的是图片的索引变化

    _currentImageIndex=(_currentImageIndex +1 )%imagearr.count;


    _centerimageview.image=[UIImageimageNamed:[NSStringstringWithFormat:@"%d.jpg",_currentImageIndex]];

    //重新设置左右图片

    leftimageindex=(_currentImageIndex+imagearr.count-1)%imagearr.count;

    rightimageindex=(_currentImageIndex +1)%imagearr.count;

    _leftimageview.image=[UIImageimageNamed:[NSStringstringWithFormat:@"%d.jpg",leftimageindex]];

    _rightimageview.image=[UIImageimageNamed:[NSStringstringWithFormat:@"%d.jpg",rightimageindex]];


    

    _page.currentPage=_currentImageIndex;

    [_scvsetContentOffset:CGPointMake(s_x,0)animated:YES];

}

#pragma mark 添加控件scrollpagecontrol

-(void)mainView{

    _scv=[[UIScrollViewalloc]init];

    _scv.frame=CGRectMake(0,0,s_x,s_y);

    _scv.contentSize=CGSizeMake(s_x * imagearr.count,0);

    //设置默认显示为s_x的地段,为默认centerimageview的位置

    [_scvsetContentOffset:CGPointMake(s_x,0)];

    //取消显示侧边滑动条

    _scv.showsHorizontalScrollIndicator=NO;

    _scv.showsVerticalScrollIndicator=NO;

    //设置整页滑动

    _scv.pagingEnabled=YES;

    //设置回弹

    _scv.bounces=YES;

    _scv.delegate=self;

    [self.viewaddSubview:_scv];

    

    _page=[UIPageControlnew];

    _page.currentPage=0;

    _page.numberOfPages=imagearr.count;

    _page.center=CGPointMake(s_x/2,s_y-100);

    _page.pageIndicatorTintColor=[UIColorcolorWithRed:0.021green:1.000blue:0.146alpha:1.000];

    [self.viewaddSubview:_page];

    

}

#pragma mark 设置imageview控件

-(void)setimageview{

    _leftimageview=[UIImageViewnew];

    _leftimageview.frame=CGRectMake(0,0,s_x,s_y);

    _leftimageview.backgroundColor=[UIColorgreenColor];

    _leftimageview.contentMode=UIViewContentModeScaleAspectFill;

    [_scvaddSubview:_leftimageview];

    

    _centerimageview=[UIImageViewnew];

    _centerimageview.frame=CGRectMake(s_x,0,s_x,s_y);

    _centerimageview.backgroundColor=[UIColorcolorWithRed:1.000green:0.453blue:0.688alpha:1.000];

    _centerimageview.contentMode=UIViewContentModeScaleAspectFill;

    [_scvaddSubview:_centerimageview];

    

    _rightimageview=[UIImageViewnew];

    _rightimageview.frame=CGRectMake(2*s_x,0,s_x,s_y);

    _rightimageview.backgroundColor=[UIColororangeColor];

    _rightimageview.contentMode=UIViewContentModeScaleAspectFill;

    [_scvaddSubview:_rightimageview];

    

    

}

#pragma mark 设置默认显示图片

-(void)setDefaultImage{

    _leftimageview.image=[UIImageimageNamed:imagearr[imagearr.count-1]];//左边显示最后一张、

    _centerimageview.image=[UIImageimageNamed:imagearr[0]];

    _rightimageview.image=[UIImageimageNamed:imagearr[1]];

    

    _currentImageIndex=0;

    _page.currentPage=_currentImageIndex;

}

#pragma mark 根据滑动的方向来判定图片如何加载

-(void)ReloadImage{

    int leftimageindex,rightimageindex;

    CGPoint offset=[_scvcontentOffset];//内容视图的位置

    if (offset.x>s_x) {//右滑

        //滑动发生后,实时变化图片加载,所以最先考虑的是图片的索引变化

        _currentImageIndex=(_currentImageIndex +1 )%imagearr.count;

        

    }

    if (offset.x<s_x) {//左滑

    /* ******************************************这个判断是重点  */

        _currentImageIndex=(_currentImageIndex +(imagearr.count-1))%imagearr.count;

    }

    

    _centerimageview.image=[UIImageimageNamed:[NSStringstringWithFormat:@"%d.jpg",_currentImageIndex]];

    //重新设置左右图片

    leftimageindex=(_currentImageIndex+imagearr.count-1)%imagearr.count;

    rightimageindex=(_currentImageIndex +1)%imagearr.count;

    _leftimageview.image=[UIImageimageNamed:[NSStringstringWithFormat:@"%d.jpg",leftimageindex]];

    _rightimageview.image=[UIImageimageNamed:[NSStringstringWithFormat:@"%d.jpg",rightimageindex]];

}

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

    //调用重新加载图片的方法

    [selfReloadImage];

    //移动到中间

    [_scvsetContentOffset:CGPointMake(s_x,0)];

    _page.currentPage=_currentImageIndex;

    

    

    

}

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

    NSLog(@"开始拖动");

    [timerinvalidate];

}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

    NSLog(@"拖动结束");

    [selfsettimer];

}

这样就可以实现 当点击拖动图片时,计时器会停止计时,待拖动结束后,计时器重新计时。

原理:3个imageview位置不变,始终显示中间的centerimageview,而left和right始终预先计算并加载要显示的图片。这样拖动时会实现循环效果,而计时器那边也是如此

其他的例如从网络获取图片,图片点击事件等等,还没写,不过都是很简单的东西,希望对各位有帮助,这段代码拿过去直接就能用