当前位置: 首页 > 科技观察

高效图片轮播,两个imageViews实现

时间:2023-03-19 16:25:08 科技观察

这种轮播框架的优点:文件少,代码简洁,不依赖任何其他第三方库,耦合度低,支持本地图片和网络图片。可以修改分页控件的位置,可以显示或隐藏自定义分页控件的图片。带图片缓存,一次性加载,永久使用性能好,内存消耗少,轮播流畅实际使用中,先看demo,代码如下运行效果轮播实现步骤接下来,笔者来分析每个方面一一。层级最底层是一个UIView,上面有一个UIScrollView和UIPageControl,scrollView上有两个UIImageView,imageView宽高=scrollview宽高=view宽高轮播原理假设轮播控件的宽度为x并且高度为y,我们设置scrollview的contentSize.width为3x,scrollview的水平偏移量为x,显示中间内容scrollView.contentSize=CGSizeMake(3x,y);scrollView.contentOffset=CGPointMake(x,0);将imageView添加到scrollviewcontentview的中间位置接下来使用代理方法scrollViewDidScroll监听scrollview滚动,定义一个枚举变量记录滚动的方向typedefenum{DirecNone,DirecLeft,DirecRight}Direction;@property(nonatomic,assign)方向;-(void)scrollViewDidScroll:(UIScrollView*)scrollView{self.direction=scrollView.contentOffset.x>x?DirecLeft:DirecRight;}使用KVO监听方向属性值的变化[selfaddObserver:selfforKeyPath:@"direction"options:NSKeyValueObservingOptionNewcontext:nil];判断滚动的方向,当偏移量大于x时,表示向左移动,则向右添加otherImageView,如果偏移量小于x,则表示向右移动,则在左侧添加otherImageView-(void)observeValueForKeyPath:(NSString*)keyPathofObject:(id)objectchange:(NSDictionary*)changecontext:(void*)context{//self.currIndex表示当前显示图片的索引,self.nextIndex表示要显示的图片的索引//_images为图片数组frame=CGRectMake(0,0,self.width,self.height);selfself.nextIndex=self.currIndex-1;if(self.nextIndex<0)self.nextIndex=_images.count–1;}elseif([change[NSKeyValueChangeNewKey]intValue]==DirecLeft){self.otherImageView.frame=CGRectMake(CGRectGetMaxX(_currImageView.frame),0,self.width,self.height);self.nextIndex=(self.currIndex+1)%_images.count;}selfself.otherImageView.image=self.images[self.nextIndex];}使用代理方法scrollViewDidEndDecelerating监听滚动结束。结束后会出现以下两种情况:此时scrollview的偏移量为0或者2x,我们再次通过代码将scrollview的偏移量设置为x,将currImageView的图片修改为otherImageView的图片——(void)scrollViewDidEndDecelerating:(UIScrollVview*)scrollView{[selfpauseScroll];}-(void)pauseScroll{self.direction=DirecNone;//清除滚动方向//判断向右滚动还是向左滚动intindex=self.scrollView.contentOffset.x/x;if(index==1)return;//等于1表示最后没有滚动,不做任何操作返回selfself.currIndex=self.nextIndex;//当前图片索引改变selfself.pageControl.currentPage=self.currIndex;self.currImageView.frame=CGRectMake(x,0,x,y);selfself.currImageView.image=self.otherImageView.image;self.scrollView.contentOffset=CGPointMake(x,0);然后我们还是看到了currImageView,但是显示下一张图片,如图所示,已经变成了原来的效果。实现自动滚动轮播功能。接下来,添加一个计时器使其自动滚动。很简单-(void)startTimer{//如果只有一张Image,直接返回,不启动定时器if(_images.count<=1)return;//如果定时器已经启动,则停止,然后重启if(self.timer)[selfstopTimer];self.timer=[NSTimertimerWithTimeInterval:self.timetarget:selfselector:@selector(nextPage)userInfo:nilrepeats:YES];[[NSRunLoopcurrentRunLoop]addTimer:self.timerforMode:NSRunLoopCommonModes];}-(void)nextPage{//动画可以改变scrollview的偏移量实现自动滚动[self.scrollViewsetContentOffset:CGPointMake(self.width*2,0)animated:YES];}注意:设置ContentOffset:animated:该方法执行后不会调用scrollview的scrollViewDidEndDecelerating方法,而是会调用scrollViewDidEndScrollingAnimation方法,所以我们需要调用pauseScroll-(void)scrollViewDidEndScrollingAnimation:(UIScrollView*)scrollView{[selfpauseScroll];在这个方法中拖动停止自动滚动当我们手动拖动图片时,我们需要停止自动滚动,此时我们只需要让定时器超时,当拖动停止时,重新启动定时器-(void)scrollViewWillBeginDragging:(UIScrollView*)scrollView{[self.timerinvalidate];}-(void)scrollViewDidEndDragging:(UIScrollView*)scrollViewwillDecelerate:(BOOL)decelerate{[selfstartTimer];}加载图片在实际开发中,我们很少旋转本地图片,大部分是server获取本地图片和网络图片都是可以的,那么如何加载呢?定义4个属性NSArrayimageArray:暴露在.h文件中,外界会将要加载的图片或路径数组赋值给该属性NSMutableArrayimages:用于存储图片的数组NSMutableDictionaryimageDic:用于缓存图片的字典,关键是URLNSMutableDictionaryoperationDic:用于保存下载操作的字典。关键是判断外部输入的是图片还是路径的URL。如果是图片,则直接添加到图片数组中。如果是路径,先添加占位图片,然后根据路径下载图片_images=[NSMutableArrayarray];for(inti=0;i