UIScrollerView当前显示3张图
代码地址如下:
http://www.demodashi.com/demo/11173.htmlWSLScrollView 功能描述:这是在继承UIView的基础上利用UIScrollerView进行了封装,支持循环轮播、自动轮播、自定义时间间隔、图片间隔、当前页码和图片大小,采用Block返回当前页码和处理当前点击事件的一个View。
一、效果图
二、实现过程
- 逻辑结构示意图
①、首先像往常一样写一个基本的UIScrollerView,会得到下图:
_scrollerView = [[UIScrollView alloc] init];_scrollerView.frame = CGRectMake((SELF_WIDTH - _currentPageSize.width) / 2, 0, _currentPageSize.width, _currentPageSize.height);_scrollerView.delegate = self;_scrollerView.pagingEnabled = YES;_scrollerView.showsHorizontalScrollIndicator = NO;[self addSubview:_scrollerView];
- 然后设置我们通常会忽略UIScrollerView的一个属性clipsToBounds为NO,默认是Yes,你会看到_scrollerView其它部分相邻的图片,但是你会发现那部分相邻的图片不会响应在它上面的任何触摸事件,因为那部分子视图超出了它的父视图,可以用响应链机制解决这个问题:
_scrollerView.clipsToBounds = NO;//处理超过父视图部分不能点击的问题,重写UIView里的这个方法
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {if ([self pointInside:point withEvent:event]) {CGPoint newPoint = [_scrollerView convertPoint:point fromView:self];for (UIImageView * imageView in _scrollerView.subviews) {if (CGRectContainsPoint(imageView.frame, newPoint)) {CGPoint newSubViewPoint = [imageView convertPoint:point fromView:self];return [imageView hitTest:newSubViewPoint withEvent:event];}}}return nil;
}
②、接下来实现循环的功能:我相信好多人也都会想到 《 4 + 0 - 1 - 2 - 3 - 4 + 0 》这个方案,也就是先在数组的最后插入原数组的第一个元素,再在第一个位置插入原数组的最后一个元素;得到如下图效果:(注意看:第一个向最后一个,最后向第一个循环过渡的时候有个Bug哦)
self.imageArray = [NSMutableArray arrayWithArray:_images];[self.imageArray addObject:_images[0]];[self.imageArray insertObject:_images.lastObject atIndex:0];//初始化时的x偏移量要向前多一个单位的_currentPageSize.width_scrollerView.contentOffset = CGPointMake(_currentPageSize.width * (self.currentPageIndex + 1), 0);
- 解决上述Bug的方案就是利用UIScrollView的两个代理方法;在前后循环过渡处,刚开始拖拽时就在Bug的位置画上对应的视图;即《 3 + 4 + 0 - 1 - 2 - 3 - 4 + 0 + 1》,结束拖拽之后,再改变UIScrollView的contentOffset,不带动画;
//开始拖拽时执行
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{//开始拖拽时停止计时器[self.timer invalidate];self.timer = nil;// 3 + 4 + 0 - 1 - 2 - 3 - 4 + 0 + 1NSInteger index = scrollView.contentOffset.x/_currentPageSize.width;//是为了解决循环滚动的连贯性问题if (index == 1) {[self.scrollerView addSubview:self.lastView];}if (index == self.imageArray.count - 2) {[self.scrollerView addSubview:self.firstView];}
}//结束拖拽时执行
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{NSInteger index = scrollView.contentOffset.x/_currentPageSize.width;//停止拖拽时打开计时器if (_isTimer) {[self statrScroll:_second];}//是为了解决循环滚动的连贯性问题if (index == 0) {scrollView.contentOffset = CGPointMake(_currentPageSize.width * (self.imageArray.count - 2) , 0);}if (index == self.imageArray.count - 1) {scrollView.contentOffset = CGPointMake(_currentPageSize.width , 0);}
}
③实现定时器自动循环轮播功能,需要解决的问题就是首尾过渡的时候,
如下图所示:解决的思路和上述类似,主要代码已标明→WSLScrollView
- (void)statrScroll:(CGFloat)second{if (_timer == nil && _isTimer) {_timer = [NSTimer scheduledTimerWithTimeInterval:second target:self selector:@selector(autoNextPage) userInfo:nil repeats:YES];}
}- (void)autoNextPage{[_scrollerView setContentOffset:CGPointMake( _currentPageSize.width * (_currentPageIndex + 1 + 1), 0) animated:YES]; if (_currentPageIndex + 2 == self.imageArray.count - 1) {//是为了解决自动滑动到最后一页再从头开始的连贯性问题[_scrollerView addSubview:self.firstView];}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{CGFloat index = scrollView.contentOffset.x/_currentPageSize.width;if (index == 0 ) {_currentPageIndex = self.imageArray.count - 1- 2;}else if(index < 1){}else if(index == self.imageArray.count - 1 || index == 1){_currentPageIndex = 0;//是为了解决自动滑动到最后一页再从头开始的连贯性问题[_scrollerView setContentOffset:CGPointMake( _currentPageSize.width , 0) animated:NO]; }else if(index == ceil(index)){_currentPageIndex = index - 1 ;}if (self.scrollEndBlock != nil) {self.scrollEndBlock(_currentPageIndex);}
}
三、项目结构图
UIScrollerView当前显示3张图
代码地址如下:
http://www.demodashi.com/demo/11173.html注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
UIScrollerView当前显示3张图相关推荐
- prefuse学习(二)显示一张图
1. 把数据以点连线的方式在画面中显示 2. 数据按照数据的性别属性使用不同的颜色 3. 鼠标左键可以把图在画面中拖动 4. 鼠标右键可以把图放大或者缩小 5. 鼠标单击某个数据上,该数据点 ...
- ctf解题--当眼花的时候,会显示两张图(隐写)
题目 不信? 你试试 解题链接: http://ctf5.shiyanbar.com/stega/final.png 解题 下载图片 wget http://ctf5.shiyanbar.com/st ...
- vue2的堆叠轮播图 (5张图 错开叠加,来回切换)
先上图: 这是一个js文件,需要在vue项目中引用这个,前提是你要下载swiper插件. export class Swiper {constructor(options) {this.$option ...
- python画多图在一个图_python pyecharts 实现一个文件绘制多张图
Grid并行显示多张图 注意: 第一个图需为 有 x/y 轴的图,即不能为 Pie,其他位置顺序任意 from pyecharts import Bar, Line, Scatter, EffectS ...
- matlab两个曲线的名称怎么显示出来的,求MATLAB的高手,怎么把两张仿真曲线合并显示在一张图上?...
求MATLAB的高手,怎么把两张仿真曲线合并显示在一张图上? 关注:194 答案:5 手机版 解决时间 2021-02-10 14:48 提问者终究是陌生了 2021-02-09 16:38 程序 ...
- css多图标在一张图内如何正确显示它们
图标在一张图内做法 参考QQ微博的做法:icon:两张图标上下结构在一张图内,需要分别显示在两个地方. icon: 需做成的样子: .header .qqwb ul li{ display: inli ...
- 使用Python中的matplotlib将多个图片显示到一张图内
在我们写论文或是汇报时,经常需要整合所得到的可视化数据结果,插入我们的论文中.如下所示的情况,我们需要将四个相关的弹性模量预测结果在一张图里展示. 使用matplotlib库中的子图(subplot) ...
- python Matplotlib 可视化总结归纳(二) 绘制多个图像单独显示多个函数绘制于一张图
1. 绘制多个图像单独显示(subplot) import numpy as np import matplotlib.pyplot as plt #创建自变量数组 x= np.linspace(0, ...
- LaTeX两张图并排显示
一.需要引入的包 \usepackage{caption} % 图片脚注 \usepackage{graphicx} \usepackage{caption} \usepackage{subfigur ...
最新文章
- AlertDialog具体解释
- 【完整代码】使用Semaphore实现限流代码示例
- opengl2 vtk 编译_编译和使用VTK时值得注意的点(待续)
- 软件系统换服务器地址,天正软件客户端修改服务器地址
- c++调用Libsvm
- python从零开始学爬虫_从零开始学爬虫(爬取豆瓣),一看就会
- Latex中将多个eps图片合并成一幅eps的代码和方法
- 如何删除vc2013上配置好的opencv
- PBR 六 材质参数
- 软件开发人员是一种很棒的职业选择的五大理由
- 苹果关掉200m限制_苹果下载超过200兆怎么设置
- 日系插画学习笔记(三):光影与结构
- 简明扼要聊聊 Vue3.0 的 Composition API 是啥东东!
- 在matlab上利用fft进行信号频谱分析_使用示波器进行信号频谱分析(FFT)的设置教学...
- 中大近代物理实验实验报告(LaTeX实现)
- CAD标注如何提取下来?这样提取很容易
- 超级壁纸android,超级壁纸大全app下载
- Linux上监控应用程序启动 (hook execve系统调用)
- 一个可以绑定多个天翼云网盘的目录列表程序,支持视频播放
- 离散行业和流程行业的区别