有段时间没有上来写博客了,主要是因为UIScrollView和UITableView的内容相对来说比较多,学完了两者我才来写总结。先从UIScrollView开始吧,例子是图片的轮播,因为UIScrollView主要是用在图片的轮播,实际开发就是广告的播放等,类似QQ列表,整个列表可以滚动,都是用UITableView。UIScrollView用起来还是比较简单的,主要是掌握它的3个属性以及它的代理。
一、UIScrollView的简单介绍
(1)滚动视图是这类多内容的控件视图中最基本的一种视图,理所当然它也就是UITextView的父类。滚动视图的大小是固定的,长宽往往不会超过屏幕的最大长宽。但是,滚动视图拥有许多内容视图,这些内容视图的大小拼接起来可以非常大,只要滚动视图包含住这些内容视图,它就有能力将它们显示出来。
(2)默认的滚动视图动作中,UIScrollView对象会检查自己的内容视图大小,如果内容视图的高没有自己的高数值大,则UIScrollView的纵向垂直方向就不会拥有滚动的特性,反之,垂直方向的滚动特性自动生效。同理水平方向也有着这样的机制,这个内容视图可能会有多个视图的重叠,UIScrollView只关心最大的内容视图拼接尺寸是多少。
(3)常见的属性:
①@property(nonatomic) CGSize contentSize; contentSize是scrollView可以滚动的区域,比如frame = (0,0,375,667) contentSize = (375,1334),代表着scrollView可以上下滚动,滚动区域为frame大小的两倍。
②@property(nonatomic) CGPoint contentOffset;contentOffset是scrollView当前显示区域顶点相对于frame顶点的偏移量,比如上个例子,若拉到最下面,则contentOffset就是(0,667),也就是y偏移了667个单位长度。
③@property(nonatomic) UIEdgeInsets contentInset;contentInset是scrollView的content view的顶点相对于scrollView的位置,比如你的contentInset = (1,100),那么你的contentView就是从scrollView的(0,100) 开始显示。
(4)如果UIScrollView无法滚动,可能是以下原因:
①没有设置contentSize;
②scrollerEnable = NO;
③没有接收到用户的触摸事件:userInteractionEnable = NO;
④没有取消autolayout功能(ps:要想scrollView滚动,必须取消autolayout)
二、图片轮播例子的相关知识点
(1)滚动尺寸的设置参考上面的简单介绍吧。
(2)隐藏滚动条:有时我们会嫌滚动条有点碍眼,这时我们可以用一句代码来去掉滚动条。水平滚动条相对应的属性showsHorizontalScrollIndicator,垂直滚动条相对应的属性showsVerticalScrollIndicator。只要我们将其值设为NO即可去掉滚动条。self.scrollView.showsHorizontalScrollIndicator = NO.
(3)设置分页。self.scrollView.pagingEnable = YES;只有我们将该属性设置为YES时,scrollView才具有一页一页的效果。不过不能实现图片轮播的效果。
(4)这里,为了记录当前滚动的页数,我们可以用pageControl来记录。即调用pageControl的numberOfPages属性来赋值。
(5)定时器NSTimer。图片轮播,不但可以让用户自由滚动,还可以在设定的时间间隔内,自动滚动图片,实现自动的图片轮播。
(6)UIScrollView的代理(delegate)。关于scrollView的代理,在我上一个博客写了,可以去参考下。
三、部分代码及其说明
(1)当我们手动滚动时,会遇到一种情况,就是当我们滚动到一个位置,就是2张图片都有的情况下,这时,我们需要计算来决定scrollView滚到第几页。下面代码的算法就是,当我们滚动到图片的一半及其以上时,我们松手,这时scrollView就会自动滚到下一页。当然,这也根据自己的喜好来更改到底是滚回当前页还是下一页,只要更改算式中的scrollW * 0.5的值就可以了。
/**
* 当scrollView正在滚动的时候调用
*/
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat scrollW = scrollView.frame.size.width;
int page = (scrollView.contentOffset.x + scrollW * 0.5) / scrollW;
self.pageControl.currentPage = page;
}
(2)之所要设置这两个方法,是有原因的。当前,不实现这两个代理方法也没问题,但是会有一个bug。当scrollView在滚动的时候,我们滚动scrollView,并且不松开鼠标,会发现,这时scrollView不会自动滚动了。但当我们松开鼠标时,scrollView就会快速的滚动几页。这是因为,虽然scrollView因为我们手动的滚动而停止了自动滚动,但是定时器NSTimer还是计算着时间。当我们松手时,scrollView就会快速滚动NSTimer所积累下来的时间。从而就造成了这个bug。因此,我们需要在我们手动滚动scrollView时,将定时器移除,在我们停止滚动时,重新开启定时器。这样定时器才不会在scrollView停止滚动时依旧计算时间。
/**
* 开始滚动
*/
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
// 移除定时器
[self removeTimer];
}
/**
* 已经停止滚动
*/
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
// 开启定时器
[self addTimer];
}
四、源代码
- (void)viewDidLoad {
[super viewDidLoad];
// 1.imageView的参数
CGFloat imagY = 0;
CGFloat imagW = self.scrollView.frame.size.width;
CGFloat imageH = self.scrollView.frame.size.height;
// 2.循环添加图片
for (int i = 0; i < KIMscorllcount; i++) {
UIImageView *imagView = [[UIImageView alloc]init];
// 设置frame
CGFloat imagX = i * imagW;
imagView.frame = CGRectMake(imagX, imagY, imagW, imageH);
// 设置图片
NSString *imagName = [NSString stringWithFormat:@"img_0%d",i + 1];
imagView.image =[ UIImage imageNamed: imagName];
// 将图片依次添加到scrollView中
[self.scrollView addSubview:imagView];
}
// 3.设置滚动的尺寸
CGFloat scrollW = KIMscorllcount * imagW;
self.scrollView.contentSize = CGSizeMake(scrollW, 0);
// 4.隐藏水平滚动条
self.scrollView.showsHorizontalScrollIndicator = NO;
// 5.分页
self.scrollView.pagingEnabled = YES;
// 6.设置pageControl的总页数
self.pageControl.numberOfPages = KIMscorllcount;
// 7.添加定时器
[self addTimer];
}
/**
* 添加定时器
*/
- (void)addTimer{
self.tiemr = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextImag) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop]addTimer:self.tiemr forMode:NSRunLoopCommonModes];
}
/**
* 移除定时器
*/
- (void)removeTimer{
[self.tiemr invalidate];
self.tiemr = nil;
}
- (void)nextImag{
// 1.增加页码
long page = 0;
if (self.pageControl.currentPage == KIMscorllcount - 1) {
page = 0;
}else{
page = self.pageControl.currentPage + 1;
}
// 2.计算滚动的位置
CGFloat offsetX = page * self.scrollView.frame.size.width;
CGPoint offset = CGPointMake(offsetX, 0);
[self.scrollView setContentOffset:offset animated:YES];
}
#pragma mark 用代理的方法实现自动滚动
/**
* 当scrollView正在滚动的时候调用
*/
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat scrollW = scrollView.frame.size.width;
int page = (scrollView.contentOffset.x + scrollW * 0.5) / scrollW;
self.pageControl.currentPage = page;
}
/**
* 用户开始手动滚动
*/
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
// 移除定时器
[self removeTimer];
}
/**
* 用户已经停止滚动
*/
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
// 开启定时器
[self addTimer];
}
@end
五、运行结果截图
六、总结
看到该博客的小伙伴,不要批判我在卖IT之家的广告啊,不过IT之家这个app确实挺不错的,有兴趣的可以去下来看看。这个图片轮播的例子所用到的图片就是从里面的图片轮播里面所下载下来的。总来的是,用UIScrollView实现图片的轮播,还是比较简单的,运用好UIScrollView的属性和代理方法就可以了。在以后的学习和实际开发中,你会发现,图片的轮播多数是用在应用的广告上,而实现图片的轮播就是UIScrollView。
——爱分享,一起学,共成长。