轮播是很多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张图,不知道是优化了,还是怎么了,还请高手们留言说一下!