天天看点

关于iOS基础总结(6)--无线轮播

1、两个imageView实现了无线轮播

· 建立一个scrollView,设置contentsize为3*kWidth,contentOffSet为kWidth

· 接下来使用代理方法scrollViewDidScroll来监听scrollview的滚动,定义一个枚举变量来记录滚动的方向

· 使用KVO来监听direction属性值的改变–>[self addObserver:self forKeyPath:@”direction” options:NSKeyValueObservingOptionNew context:nil];

· 通过observeValueForKeyPath判断滚动的方向,当偏移量大于x,表示左移,则将otherImageView加在右边,偏移量小于x,表示右移,则将otherImageView加在左边。同时判断设置对应的索引

· 通过代理方法scrollViewDidEndDecelerating来监听滚动结束,结束后,scrollview的偏移量为0或者2x,我们通过代码再次将scrollview的偏移量设置为x,并将currImageView的图片修改为otherImageView的图片,那么我们看到的还是currImageView,只不过展示的是下一张图片

,然后设置自动轮播,添加计时器,利用setContentOffset方法里面setContentOffset:animated:方法执行完毕后不会调用scrollview的scrollViewDidEndDecelerating方法,但是会调用scrollViewDidEndScrollingAnimation方法,因此我们要在该方法中调用pauseScroll(即监听减速结束后由otherImageView切换到currImageView的方法)

· 添加计时器:self.timer = [NSTimer timerWithTimeInterval:self.time target:self selector:@selector(nextPage) userInfo:nil repeats:YES];

· 在scrollViewWillBeginDragging中停止计时器

· 在scrollViewDidEndDragging中开启计时器

· 判断外界传入的是图片还是路径,如果是图片,直接加入图片数组中,如果是路径,先添加一个占位图片,然后根据路径去下载图片

· 监听图片被点击

定义一个block属性暴露给外界void(^imageClickBlock)(NSInteger index)
(不会block的可以用代理,或者看这里)

设置currImageView的userInteractionEnabled为YES

给currImageView添加一个点击的手势

在手势方法里调用block,并传入图片索引
           

· NSTimer的两种形式

scheduledTimerWithTimeInterval 是创建一个定时器,并加入到当前运行循环[NSRunLoop currentRunLoop]中

其他两个([NSTimer timerWithTimeInterval: target:self selector:@selector(doSomeThing1) userInfo:nil repeats:YES]; [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:] interval: target:self selector:@selector(doSomeThing2) userInfo:nil repeats:YES];)只是创建定时器,并未添加到当前运行循环中,所以如果是其他两种方式创建的定时器则需要手动添加到currentRunLoop中
           

· NSTimer是普通的定时器,如果系统繁忙,刷新可能会被延迟。但是CADisplaylink实时刷新,跟着屏幕的刷新频率实时刷新,60次/s,与屏幕刷新频率相同

2、三个imageview实现无线轮播的大致原理

· 将3个imageview添加到scrollview上面,scrollview的contensize是3个imageview的宽度,设置scrollview一开始初始的偏移量为一个imageview宽度,因为里面有3个UIImageView,所以scrollview默认显示的就是中间的那个imageview,并且关键就是让屏幕显示的始终就是中间的这个imagview

· 使用3个imageview来回更换图片,并在每一次更换图片后立即再设置scrollview偏移量还为一个imagview的宽度,也就是让scrollview滚动后再滚回原来默认的位置,这样就可以达到始终显示中间那个imageview的效果

ps:例如要使用三个UIImageView循环显示5张图片

1)由于中间的imageview是显示在屏幕上的,它需要在启动时默认显示第1张图片,那么左边的imagview

自然就需要显示最后一张图片,右边的imagview自然要显示第二张图片了.所以一开始肯定默认放图片5、

图片1、图片2,当前显示中间的UIImageView,也就是图片1

2)如果用户手指向左滑动,那么就会显示图片2,当图片2显示完整后迅速重新设置左中右三个UIImageView

的内容为图片1、图片2、图片3,然后马上设置contentOffset再次为一开始默认的一个imageview宽度,

让它滚回默认一开始的位置,以此来达到一直显示的是中间的UIImageView的效果,此刻中间那个imagview

显示的也就是图片2

3)继续向左滑动看到图片3,当图片3滚动完成迅速重新设置3个UIImageView的内容为图片2、图片3、图片

4,然后通过设置contentOffset依然显示中间的那个UIImageView,此刻也就是图片3

5)当然,向右滑动原理完全一样,如此操作就给用户一种循环的错觉,而且图片多的话不占用过多内存