iOS之图片轮播代码共享

我们在做项目是有时候会遇到图片轮播:

DEMO:

.h

复制代码
#import <UIKit/UIKit.h>

@interface ImagePlayView : UIView<UIScrollViewDelegate>

@property (nonatomic, strong) UIScrollView * scroll;
@property (nonatomic, strong) UIPageControl * play;
@property (nonatomic, strong) NSTimer * timer;

@end
复制代码

.m

复制代码
#import "ImagePlayView.h"

@implementation ImagePlayView

- (id) initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame])
    {
        //创建一个UIscrollView组件,作为滚动组件的头视图
        CGRect headScroll = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
        _scroll = [[UIScrollView alloc] initWithFrame:headScroll];
        //取消水平滚动条
        _scroll.showsHorizontalScrollIndicator = NO;
        //取消弹性设置
        _scroll.bounces = NO;
        //设置分页
        _scroll.pagingEnabled = YES;
        [self addSubview: _scroll];
        for (int i = 0; i < 3 ; i ++)
        {
            UIImageView * imageV = [[UIImageView alloc] initWithFrame:CGRectMake(i * self.frame.size.width, 0, self.frame.size.width, self.frame.size.height)];
            imageV.image = [UIImage imageNamed:[NSString stringWithFormat:@"banner-%d",i + 1]];
            [_scroll addSubview: imageV];
        }
        _scroll.contentSize = CGSizeMake(3 * self.frame.size.width, 0);
        _scroll.delegate = self;
        
        //设置分页指示器
        _play = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width/3, 20)];
        //设置分页器的位置
        _play.center = CGPointMake(self.frame.size.width/2, self.frame.size.height/1.2);
        // 设置其它页指示器圆点的颜色
        _play.pageIndicatorTintColor = [UIColor grayColor];
        // 设置当前页指示器圆点的颜色
        _play.currentPageIndicatorTintColor = [UIColor grayColor];
        // 设置分页器的页数
        _play.numberOfPages = 3;
        // 设置当前是第几页
        _play.currentPageIndicatorTintColor = 0;
        [self addSubview:_play];
        
        //设置计时器
        _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(time) userInfo:nil repeats:YES];
        // 先获取当前的消息循环,利用消息循环设置计时器对象的优先级和控件的优先级相同
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop addTimer:self.timer forMode:NSRunLoopCommonModes];

    }
    return self;
}

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    // 解决第一个Bug:按住滚动内容拖拽或不松手,一旦松手就会滚动好多次。解决方法当开始拖动时令计时器失效。当拖动结束后再新建一个计时器
    [self.timer  invalidate];
    // 计时器一旦失效,就不能再使用了。所以赋给它一个空指针
    self.timer = nil;
}

//  在拖动的过程中会执行这个方法
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //  先获根据内容的偏移位置,获取当前的页数
    int  page =( scrollView.contentOffset.x+scrollView.frame.size.width*0.5)/ scrollView.frame.size.width;
    
    //  在拖动的过程中把当前的页码告知分页控制器组件
    self.play.currentPage = page;
}

// 在拖动结束后会执行这个方法
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    // 当拖动结束后再新建一个计时器, 第一个Bug解除了
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(time) userInfo:nil repeats:YES];
    
    // 解决第二个BUg:当拖动点击别的控件时。将停止滚动,这是由于单线程执行,而计时器对象和网络对象的优先级小于控件的优先级,所以当拖动控件时,就不会再执行NSTimer计时器对象的操作。解决方法如下:每当新建一个NSTimer计时器,就先获取当前的消息循环,并在消息循环中设置它的优先级和控件的优先级相同,这时程序会分时间片给优先级相同的对象;
    NSRunLoop *runRoop = [NSRunLoop currentRunLoop];  // 获取当前的消息循环
    
    //  利用消息循环为timer对象设置优先级和控件的优先级相同
    [runRoop addTimer:self.timer forMode:NSRunLoopCommonModes];
    
}


- (void) time
{
    
    // 获取当前的页数
    NSInteger page = self.play.currentPage;
    if (page == self.play.numberOfPages-1) {
        page = 0;
    }else{
        page++;
    }
    
    // 根据当前的页数计算内容偏移量contentOffset的大小
    // 通过代码设置contentOffset偏移,实现自动滚动
    // 非动画方式
    //self.scrollView.contentOffset = CGPointMake(page*self.scrollView.frame.size.width, 0);
    
    // 通过动画方式
    [self.scroll setContentOffset:CGPointMake(page*self.scroll.frame.size.width, 0) animated:YES];

}

@end
复制代码

 

你可能感兴趣的:(iOS之图片轮播代码共享)