初学了UIScrollView的分页的功能,只能说iOS中UIScrollView这玩意儿功能太强了,除了有类似于android中的scrollview的功能,还有Viewpager的功能,比如做app引导页、图片轮播器等,android中一般用viewpager来做,iOS却可以用UIScrollView来做,而且实现起来比android要简单。

    封装后的好处就是,在ViewController中只需要创建一个自定义的View对象,设置好尺寸图片以及相应的颜色并把她添加到父控件中,就能正常使用了。。也就是说,要把UIScrollView和UIPageControl的初始化、设置数据,分页,设置属性等等相应的操作都在我自定义的View类中进行。在头文件中提供一些接口供外部去使用,而不暴露内部实现。

还是和之前一样,创建好xib文件,自定义的view类,在xib中放UIScrollView和UIPageControl,修改xib中的View的class,定义属性、构造方法,重写setter方法,监听UIScrollView的滚动。。。。balabala

XXPageView.h

//
//  XXPageView.h
//  UIScrollView的简单封装
//
//  Created by Daniel on 16/3/6.
//  Copyright © 2016年 Daniel. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface XXPageView : UIView

+ (instancetype)pageView;

/** 图片名字 */
@property(nonatomic, strong) NSArray *imageNames;

/** UIPageControl当前圆点的颜色 */
@property(nonatomic, strong) UIColor *currentColor;

/** UIPageControl其他圆点的颜色 */
@property(nonatomic, strong) UIColor *otherColor;

@end
//
//  XXPageView.h
//  UIScrollView的简单封装
//
//  Created by Daniel on 16/3/6.
//  Copyright © 2016年 Daniel. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface XXPageView : UIView

+ (instancetype)pageView;

/** 图片名字 */
@property(nonatomic, strong) NSArray *imageNames;

/** UIPageControl当前圆点的颜色 */
@property(nonatomic, strong) UIColor *currentColor;

/** UIPageControl其他圆点的颜色 */
@property(nonatomic, strong) UIColor *otherColor;

@end

XXPageView.m

//
//  XXPageView.m
//  UIScrollView的简单封装
//
//  Created by Daniel on 16/3/6.
//  Copyright © 2016年 Daniel. All rights reserved.
//

#import "XXPageView.h"
@interface XXPageView() <UIScrollViewDelegate>
/** 这里的属性 以及scrollview的代理我都是用拖线的方式来的 */
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

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

@implementation XXPageView

+ (instancetype)pageView {
    //加载xib
    return [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass(self) owner:nil options:nil]lastObject];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    //这些设置尺寸应该可以用autoLayout来搞吧,现在还不会用autoLayout,后面再来优化
    
    // 设置scrollView的frame
    self.scrollView.frame = self.bounds;
    
    // 获得scrollview的尺寸
    CGFloat scrollW = self.scrollView.frame.size.width;
    CGFloat scrollH = self.scrollView.frame.size.height;
    
    // 设置pageControl
    CGFloat pageW = 100;
    CGFloat pageH = 20;
    CGFloat pageX = scrollW - pageW;
    CGFloat pageY = scrollH - pageH;
    self.pageControl.frame = CGRectMake(pageX, pageY, pageW, pageH);
    
    // 设置内容大小
    self.scrollView.contentSize = CGSizeMake(self.imageNames.count * scrollW, 0);
    
    // 设置所有imageView的frame
    for (int i = 0; i<self.scrollView.subviews.count; i++) {
        UIImageView *imageView = self.scrollView.subviews[i];
        imageView.frame = CGRectMake(i * scrollW, 0, scrollW, scrollH);
    }
}

#pragma mark - setter方法重写
- (void)setImageNames:(NSArray *)imageNames {
    _imageNames = imageNames;
    //先移除之前所有的imageview
    //makeObjectsPerformSelector 让所有的objects都执行某个方法
    [self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    
    //根据图片名创建对应的imageView并添加到UIScrollView中
    for (int i = 0; i < imageNames.count; i++) {
        UIImageView *imageView = [[UIImageView alloc]init];
        imageView.image = [UIImage imageNamed:imageNames[i]];
        [self.scrollView addSubview:imageView];
    }
    
    //开启分页功能,也可以在xib中设置
    //self.scrollView.pagingEnabled = YES;
    
    //设置总页数
    self.pageControl.numberOfPages = imageNames.count;
    
    //当只有一个控件时隐藏pageControl
    //这句代码也可以在xib文件中设置
    //self.pageControl.hidesForSinglePage = YES;
    
    //这种方法也可以
    //self.pageControl.hidden = imageNames.count <=1;
    
}

/** 设置当前圆点的颜色 */
-(void)setCurrentColor:(UIColor *)currentColor {
    _currentColor = currentColor;
    self.pageControl.currentPageIndicatorTintColor = currentColor;
}

/** 设置其他圆点的颜色 */
- (void)setOtherColor:(UIColor *)otherColor {
    _otherColor = otherColor;
    self.pageControl.pageIndicatorTintColor = otherColor;
}

#pragma mark - <UIScrollViewDelegate>
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    self.pageControl.currentPage = (int)(scrollView.contentOffset.x / scrollView.frame.size.width + 0.5);
}

@end
//
//  XXPageView.m
//  UIScrollView的简单封装
//
//  Created by Daniel on 16/3/6.
//  Copyright © 2016年 Daniel. All rights reserved.
//

#import "XXPageView.h"
@interface XXPageView() <UIScrollViewDelegate>
/** 这里的属性 以及scrollview的代理我都是用拖线的方式来的 */
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

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

@implementation XXPageView

+ (instancetype)pageView {
    //加载xib
    return [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass(self) owner:nil options:nil]lastObject];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    //这些设置尺寸应该可以用autoLayout来搞吧,现在还不会用autoLayout,后面再来优化
    
    // 设置scrollView的frame
    self.scrollView.frame = self.bounds;
    
    // 获得scrollview的尺寸
    CGFloat scrollW = self.scrollView.frame.size.width;
    CGFloat scrollH = self.scrollView.frame.size.height;
    
    // 设置pageControl
    CGFloat pageW = 100;
    CGFloat pageH = 20;
    CGFloat pageX = scrollW - pageW;
    CGFloat pageY = scrollH - pageH;
    self.pageControl.frame = CGRectMake(pageX, pageY, pageW, pageH);
    
    // 设置内容大小
    self.scrollView.contentSize = CGSizeMake(self.imageNames.count * scrollW, 0);
    
    // 设置所有imageView的frame
    for (int i = 0; i<self.scrollView.subviews.count; i++) {
        UIImageView *imageView = self.scrollView.subviews[i];
        imageView.frame = CGRectMake(i * scrollW, 0, scrollW, scrollH);
    }
}

#pragma mark - setter方法重写
- (void)setImageNames:(NSArray *)imageNames {
    _imageNames = imageNames;
    //先移除之前所有的imageview
    //makeObjectsPerformSelector 让所有的objects都执行某个方法
    [self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    
    //根据图片名创建对应的imageView并添加到UIScrollView中
    for (int i = 0; i < imageNames.count; i++) {
        UIImageView *imageView = [[UIImageView alloc]init];
        imageView.image = [UIImage imageNamed:imageNames[i]];
        [self.scrollView addSubview:imageView];
    }
    
    //开启分页功能,也可以在xib中设置
    //self.scrollView.pagingEnabled = YES;
    
    //设置总页数
    self.pageControl.numberOfPages = imageNames.count;
    
    //当只有一个控件时隐藏pageControl
    //这句代码也可以在xib文件中设置
    //self.pageControl.hidesForSinglePage = YES;
    
    //这种方法也可以
    //self.pageControl.hidden = imageNames.count <=1;
    
}

/** 设置当前圆点的颜色 */
-(void)setCurrentColor:(UIColor *)currentColor {
    _currentColor = currentColor;
    self.pageControl.currentPageIndicatorTintColor = currentColor;
}

/** 设置其他圆点的颜色 */
- (void)setOtherColor:(UIColor *)otherColor {
    _otherColor = otherColor;
    self.pageControl.pageIndicatorTintColor = otherColor;
}

#pragma mark - <UIScrollViewDelegate>
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    self.pageControl.currentPage = (int)(scrollView.contentOffset.x / scrollView.frame.size.width + 0.5);
}

@end


<补充start>

这种图片轮播一般都是可以拖拽滑动,也可以定时滑动的,现在给她加一个定时器,还是监听UIScrollView的滚动,对scrollViewWillBeginDragging方法和scrollViewDidEndDragging方法重写,去控制定时器的开关,定时器中间隔多长时间后执行跳转到下一页的方法即可。

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self stopTimer];
}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    [self startTimer];
}

#pragma mark - 定时器控制
-(void)startTimer {
    //创建一个定时器
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
    
    //解决当同界面的其他控件滚动时,定时器失效的问题
    [[NSRunLoop mainRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];
}

-(void)stopTimer {
    [self.timer invalidate];
    self.timer = nil;
}

//滚动到下一页
-(void)nextPage {
    NSInteger page = self.pageControl.currentPage + 1;
    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];
}
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self stopTimer];
}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    [self startTimer];
}

#pragma mark - 定时器控制
-(void)startTimer {
    //创建一个定时器
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
    
    //解决当同界面的其他控件滚动时,定时器失效的问题
    [[NSRunLoop mainRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];
}

-(void)stopTimer {
    [self.timer invalidate];
    self.timer = nil;
}

//滚动到下一页
-(void)nextPage {
    NSInteger page = self.pageControl.currentPage + 1;
    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];
}

还有,加载xib的方式中,xib或者storyboard中的控价创建完之后,会调用awakeFromNib这个方法,所以初始化完之后在该方法中开启定时器即可。

/** 当控件从xib\storyboard中创建完毕时,就会调用这个方法,创建完毕后的初始化操作,在这个方法中执行 */
- (void)awakeFromNib {
    [self setup];
}

/** 初始化代码 */
- (void)setup {
    // 开启定时器
    [self startTimer];
}
/** 当控件从xib\storyboard中创建完毕时,就会调用这个方法,创建完毕后的初始化操作,在这个方法中执行 */
- (void)awakeFromNib {
    [self setup];
}

/** 初始化代码 */
- (void)setup {
    // 开启定时器
    [self startTimer];
}

<补充end>


XXPageView.xib

也可以在代码中设置

设置XXPageView为UIScrollView的代理

最后在ViewController中调用

//
//  ViewController.m
//  UIScrollView分页控件的简单封装
//
//  Created by Daniel on 16/3/6.
//  Copyright © 2016年 Daniel. All rights reserved.
//

#import "ViewController.h"
#import "XXPageView.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //直接创建一个XXPageView
    XXPageView *pageView = [XXPageView pageView];
    
    //设置frame
    pageView.frame = CGRectMake(37, 50, 300, 200);
    
    //设置图片内容
    pageView.imageNames = @[@"img_00", @"img_01", @"img_02",@"img_03",@"img_04"];
    
    //设置pageControl相应的颜色
    pageView.currentColor = [UIColor orangeColor];
    pageView.otherColor = [UIColor grayColor];
    
    [self.view addSubview:pageView];
}

@end
//
//  ViewController.m
//  UIScrollView分页控件的简单封装
//
//  Created by Daniel on 16/3/6.
//  Copyright © 2016年 Daniel. All rights reserved.
//

#import "ViewController.h"
#import "XXPageView.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //直接创建一个XXPageView
    XXPageView *pageView = [XXPageView pageView];
    
    //设置frame
    pageView.frame = CGRectMake(37, 50, 300, 200);
    
    //设置图片内容
    pageView.imageNames = @[@"img_00", @"img_01", @"img_02",@"img_03",@"img_04"];
    
    //设置pageControl相应的颜色
    pageView.currentColor = [UIColor orangeColor];
    pageView.otherColor = [UIColor grayColor];
    
    [self.view addSubview:pageView];
}

@end

效果图:

咦,为啥pageControl在右下角啊?我在xib中设置的是居中啊,妈蛋。。。