免费开源的iOS开发学习平台

UIPageControl详解:2-UIPageControl实际应用

图片轮播器是App中常用的组件,经常用于广告播放或者重点新闻的图文展示。图片轮播器是通常情况下是由UIScrollView、UIImageView、UIPageControl三个控件组合而成的。本节的示例代码完成了一个简单的图片轮播器的功能实现。

准备工作

通常App中的轮播图素材来源于服务器,以便可以随时更新其中显示的内容。我们直接导入4张本地图片用作替代(注意图片的命名规律),实现的原理是完全相同的。

自定义UIScrollView类

图片轮播器之所以可以实现图片水平滑动,主要是使用到了UIScrollView的特性。因此,我们需要首先创建一个UIScrollView,然后把所有需要显示的图片依次平铺式的布局在UIScrollView上。

创建一个继承于UIScrollView的MYScrollView类,并在MYScrollView.m文件中添加其属性设置的代码。其中,contentSize的width是根据图片的数量而设定的,简单期间,我们设置每张图片的宽度与屏幕宽度相同,这样可以使图片占满整个屏幕的宽度。

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        CGFloat contentSizeWidth = [UIScreen mainScreen].bounds.size.width * 4;
        self.contentSize = CGSizeMake(contentSizeWidth, 0);
        self.contentOffset = CGPointZero;
        self.pagingEnabled = YES;
        self.showsHorizontalScrollIndicator = NO;
        self.showsVerticalScrollIndicator = NO;
        self.bounces = NO;
        self.clipsToBounds = NO;
        [self addImageView];
    }
    return self;
}

在UIScrollView中添加4个UIImageView子控件来放置图片,注意addImageView方法需要在initWithFrame:中调用。

- (void) addImageView {
    for (int i = 0; i < 4; i++) {
        //获取到图片的宽度
        NSString *imageName = [NSString stringWithFormat:@"99logo_%02d.jpg",i];
        UIImage *image = [UIImage imageNamed:imageName];
        CGFloat imageWidth = image.size.width;
        CGFloat imageHeight = image.size.height;
        CGFloat imageWHRatio = imageWidth/imageHeight;
        CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
        CGFloat imageViewX = i * screenWidth;
        //根据图片的实际宽度计算显示出来后图片的高度(不失真)
        CGFloat imageViewHeight = screenWidth / imageWHRatio;
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(imageViewX, 0, screenWidth, imageViewHeight)];
        imageView.image = image;
        //添加图片到scrollveiw
        [self addSubview:imageView];        
    }    
}

创建MYScrollView对象

在ViewController中添加一个MYScrollView类型的属性,并在懒加载中设置其外观属性,并且不要忘记在viewDidLoad方法中添加该子控件。

@property (nonatomic,strong) MYScrollView *myScrollView;
- (MYScrollView *)myScrollView {
    if (_myScrollView == nil) {
        //获取到图片的宽度
        UIImage *image = [UIImage imageNamed:@"99logo_00"];
        CGFloat imageWidth = image.size.width;
        CGFloat imageHeight = image.size.height;
        CGFloat imageWHRatio = imageWidth/imageHeight;
        //把图片添加到scrollView中,关键在于设置位置(平铺式的布局)
        CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
        //根据图片的实际宽度计算显示出来后图片的高度(不失真)
        CGFloat imageViewHeight = screenWidth / imageWHRatio;
        _myScrollView = [[MYScrollView alloc]initWithFrame:CGRectMake(0, 20, [UIScreen mainScreen].bounds.size.width,imageViewHeight)];
    }
    return _myScrollView;
}

添加UIPageControl

在ViewController上添加一个UIPageControl类型的属性,对UIPageControl初始化并设置其属性。同样,不要忘记在viewDidLoad方法中添加子控件。

@property (nonatomic,strong) UIPageControl *pageControl;
- (UIPageControl *)pageControl{
    if (_pageControl == nil) {
        _pageControl = [[UIPageControl alloc] init];
        _pageControl.frame = CGRectMake(0, 215, [UIScreen mainScreen].bounds.size.width, 37);
        _pageControl.numberOfPages = 4;
        _pageControl.currentPage = 0;
        _pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
        _pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
        //监控用户对于pageControl的点击事件
        [_pageControl addTarget:self action:@selector(clickPageControl) forControlEvents:UIControlEventValueChanged];
    }
    return _pageControl;
}

实现pageControl的点击事件,点击不同的位置会跳转到对应的图片。其中,currentImageIndex是当前的图片索引。

- (void) clickPageControl {
    //根据点击的pageControl的值,来更新scrollview的contentoffset
    CGFloat x = [UIScreen mainScreen].bounds.size.width * self.pageControl.currentPage;
    [self.myScrollView setContentOffset:CGPointMake(x, 0) animated:YES];    
    //更新一下currentImageIndex的值
    self.currentImageIndex = (int)self.pageControl.currentPage;    
}

设置计时器

我们通常看到的图片轮播器都是自动播放的,我们要实现这个功能可以添加一个NSTimer对象用于计时处理。

@property (nonatomic, strong) NSTimer *timer;
- (void)viewDidLoad {
    [super viewDidLoad];
    //为了明确图片位置,将view背景设置为灰色
    self.view.backgroundColor = [UIColor grayColor];
    //添加scrollView
    [self.view addSubview:self.myScrollView];
    //添加pageControl
    [self.view addSubview:self.pageControl];  
    //应用一启动,就立即启动计时器
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(changeImage) userInfo:nil repeats:YES];
    self.currentImageIndex = 0;
}

定时器启动后会定时调用changeImage方法,以实现图片轮播效果。

- (void)changeImage {
    //更新pageControl的值
    self.pageControl.currentPage = self.currentImageIndex;
    //计算每次偏移的x值
    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    CGFloat x = screenWidth * self.currentImageIndex++;
    [self.myScrollView setContentOffset:CGPointMake(x, 0) animated:YES]; 
    //重新更新index的值
    if (self.currentImageIndex == 4) self.currentImageIndex = 0; 
}

运行效果:

素材下载

本节使用的素材下载地址:九九学院github素材库

示例代码

https://github.com/99ios/10.3.2