UIScrollView打造轮播效果

作者: 世外大帝 | 来源:发表于2016-12-11 21:34 被阅读49次

    轮播是很多APP必备组件,正好这两天在看UIScrollView,就想到这个可以做轮播,也可以做欢迎页。

    直接用代码描述吧

    代码实现

    #import "ViewController.h"
    
    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        //图片个数
        int ImageCount = 3;
        //scrollview的宽和高
        CGFloat width = self.scrollView.frame.size.width;
        CGFloat height = self.scrollView.frame.size.height;
        
        //加载图片
        for(int i=0;i<ImageCount;i++){
            UIImageView* imageView = [[UIImageView alloc]init];
            
            imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"image0%d",i]];
            imageView.frame = CGRectMake(i*width, 0, width, height);
            [self.scrollView addSubview:imageView];
            
        }
        
        //设置内容大小
        CGFloat contentWidth = ImageCount * width;
        self.scrollView.contentSize = CGSizeMake(contentWidth, 0);
        
        //去掉滚动条
        self.scrollView.showsVerticalScrollIndicator = NO;
        self.scrollView.showsHorizontalScrollIndicator = NO;
        
        //开启分页功能
        //这里是根据ScrollView的宽度自动进行切割的
        self.scrollView.pagingEnabled = YES;
        
    
    }
    
    
    
    @end
    

    上面的代码已经实现了图片切换效果,但是目前还缺少图片指示器,我记得以前写android的时候是用两个ImageView来回切换,不过IOS是有这个控件的,叫UIPageControl,直接在storyboard中拖上去,然后调整一下位置,如果直接拖到scrollView上,你会惊奇的发现,它跑到scrollView里面去了,所以还是手动调整吧

    @property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
    

    这时候我们需要监听它的滚动,把它和UIScrollView绑定了,好,继续熟悉代理去:

    我先把UIScrollView的代理拖到ViewControl上,然后回到代码遵守协议去:
    //设置ScrollView的代理

        @interface ViewController ()<UIScrollViewDelegate>
    
        //设置代理
        self.scrollView.delegate = self;
    
    #pragma 实现代理方法
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView{
        
        //do something
        
        
    }
    
    //我们就在DidScroll里面监听它的滚动,在这里面写UIPageControl的相关设置:
    #pragma 实现代理方法
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView{
        //计算当前页
           int currentPage = scrollView.contentOffset.x / scrollView.frame.size.width;
        self.pageControl.currentPage = currentPage;
        
    }
    

    到此为止,一个基本的功能就做好了。

    封装组件:

    以前做Android的时候深得各位大神开源代码的帮助,所以我们也要学习一下封装,比如说,我们的代码想这样用:

    JTYPageView* pageView = [JTYPageView pageView];
    //设置frame
    pageView.frame = CGRectMake(37, 30, 300, 300);
    //加载图片    
    pageView.imageNames = @[@"image01",@"image02",@"image03"];
    //设置指示器颜色    
    pageView.hintPageControlColor = [UIColor yellowColor];
    pageView.currentPageControlColor = [UIColor blackColor];
    [self.view addSubview:pageView];
    

    接下来试试能封装成啥球样:

    自定义xib:

    画一个默认样式就行,怎么好看怎么来,反正是初始的,记得去掉滚动条,不然有点丑

    定义头文件:

    JTYPageView.h
    
    +(instancetype) pageView;
    
    /** 图片数据 */
    @property (nonatomic,strong) NSArray*imageNames;
    

    实现:

    #import "JTYPageView.h"
    
    @interface JTYPageView()<UIScrollViewDelegate>
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    @property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
    
    /**
     * pageView
     */
    +(instancetype)pageView{
        return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject];
    }
    
    /**
     * 设置pageControl颜色
     */
    -(void)setCurrentPageControlColor:(UIColor *)currentPageControlColor{
        _currentPageControlColor = currentPageControlColor;
        self.pageControl.currentPageIndicatorTintColor = currentPageControlColor;
    }
    -(void)setHintPageControlColor:(UIColor *)hintPageControlColor{
        _hintPageControlColor = hintPageControlColor;
        self.pageControl.pageIndicatorTintColor = hintPageControlColor;
    }
    /**
     * 设置图片名称
     */
    -(void)setImageNames:(NSArray *)imageNames{
        _imageNames = imageNames;
        //根据图片名称创建对应个数的ImageView
        for(int i=0;i<imageNames.count;i++){
            UIImageView* imageView = [[UIImageView alloc]init];
            imageView.image = [UIImage imageNamed:imageNames[i]];
            [self.scrollView addSubview:imageView];
            
        }
        //设置总页数
        self.pageControl.numberOfPages = imageNames.count;
        //单页隐藏
        self.pageControl.hidesForSinglePage = YES;
    }
    
    /**
     * 布局
     */
    -(void)layoutSubviews{
        [super layoutSubviews];
        
    
        //设置scrollView的frame
        self.scrollView.frame = self.bounds;
        
        //获得scrollView的尺寸
        CGFloat scrollWidth = self.scrollView.frame.size.width;
        CGFloat scrollHeight = self.scrollView.frame.size.height;
        
        
    
        //设置pageControl
        CGFloat pageControlWidth = 100;
        CGFloat pageControlHeight = 20;
        CGFloat pageControlX = scrollWidth - pageControlWidth;
        CGFloat pageControlY = scrollHeight - pageControlHeight;
        self.pageControl.frame = CGRectMake(pageControlX, pageControlY, pageControlWidth, pageControlHeight);
        
        
        //设置内容大小
        self.scrollView.contentSize = CGSizeMake(self.imageNames.count*scrollWidth, 0);
        //设置所有ImageView的frame
        for (int i=0; i<self.scrollView.subviews.count; i++) {
            UIImageView * imageView = self.scrollView.subviews[i];
            imageView.frame = CGRectMake(scrollWidth * i, 0, scrollWidth, scrollHeight);
        }
        
    }
        /**
         * 监听滚动
         */
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView{
        self.pageControl.currentPage = scrollView.contentOffset.x / scrollView.frame.size.width;
        
        
    }
    

    不知道注释是否够详细?

    指示器控制:

    指示器由两部分构成,一个是负责当前的,我们姑且叫做current,另一个是负责待选的,我们暂且叫做hint,先定义两个接口

    JTYPageView.h
    
    /** 待选控制器颜色 */
    @property (nonatomic,strong) UIColor*hintPageControlColor;
    /** 当前控制器颜色 */
    @property (nonatomic,strong) UIColor*currentPageControlColor;
    

    然后实现它们

    JTYPageView.m
    
    /**
     * 设置pageControl颜色
     */
    -(void)setCurrentPageControlColor: (UIColor *)currentPageControlColor{
        _currentPageControlColor = currentPageControlColor;
        self.pageControl.currentPageIndicatorTintColor = currentPageControlColor;
    }
    -(void)setHintPageControlColor: (UIColor *)hintPageControlColor{
        _hintPageControlColor = hintPageControlColor;
        self.pageControl.pageIndicatorTintColor = hintPageControlColor;
    }
    

    好了,那么接下来在Control中是这么用的

        pageView.hintPageControlColor = [UIColor yellowColor];
        pageView.currentPageControlColor = [UIColor blackColor];
    

    定时器

    我们的轮播得让它自动滚动啊,所以设置一个简易的定时器功能,当然,这个定时器,作为初学者的我们也可以好好封装一下,将来用作其他用途。

    这个需要在代码开始的地方加载,那么,我们还得加代码- -!踏马的,挺简单一个功能,让我越写越多了

    //当控件通过代码创建时,调用这个方法
    -(instancetype)initWithFrame:(CGRect)frame{
        if(self = [super initWithFrame:frame]){
            [self startTimer];
        }
        
        return self;
    }
    //通过xib的时候,调用这个方法
    -(void)awakeFromNib{
        [self startTimer];
    }
    
    //定时器
    -(void)startTimer{
        /**
         * param1:timer 间隔时间
         * param2:target 目标
         * param3:selector 选择器方法
         * param4:userInfo 我们暂时用不到
         * param5:repeats 是否重复滚动
         */
        [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
    }
    //定时器中的下一页功能
    -(void)nextPage{
        //页数
        NSInteger page = self.pageControl.currentPage + 1;
        //如果page达到总页数,让它回到第一页
        if (page == self.pageControl.numberOfPages) {
            page = 0;
        }
        
        //内容的偏移量
        CGPoint offset = self.scrollView.contentOffset;
        offset.x = page * self.scrollView.frame.size.width;
        
        //设置偏移量,带动画效果
        [self.scrollView setContentOffset:offset animated:YES];
        NSLog(@"next");
        
        
    }
    
    

    上面是一个轮播效果,当然,也可以做引导页,只需要适配屏幕大小就行了,但是有个问题我还是没搞明白,之前一个大神说是这样做可能会引发内存问题,然后运行在Xcode6上的时候会显示全部图片,但是我用的Xcode8.1,只显示1张图,不知道是优化了,还是怎么了,还请高手们留言说一下!

    相关文章

      网友评论

        本文标题:UIScrollView打造轮播效果

        本文链接:https://www.haomeiwen.com/subject/rswpmttx.html