初学了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中设置的是居中啊,妈蛋。。。