博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[iOS]圆形进度条及计时功能
阅读量:4306 次
发布时间:2019-06-06

本文共 2185 字,大约阅读时间需要 7 分钟。

平时用战网安全令的时候很喜欢圆形倒计时的效果,然后简单看了一下Android的圆形进度条,后来又写了一个IOS的。整体界面参照IOS系统的倒计时功能,顺便熟悉了UIPickerView的一些特性的实现方法。完整代码可以看:。

其实没什么难度,下面记录几个要点
:

放个预览图

Screen%20Shot%202015-10-10%20at%2011.10.22%20AM.png?raw=true

Screen%20Shot%202015-10-10%20at%2011.10.35%20AM.png?raw=true


画圆

用的贝塞尔曲线UIBezierPath来画,这个类支持画很多种形状,可以单独去尝试。

UIBezierPath *progress = [UIBezierPath bezierPath];[progress addArcWithCenter:CGPointMake(rect.size.width / 2, rect.size.height / 2)                      radius:RADIUS                  startAngle:startAngle                    endAngle:endAngle                   clockwise:YES];progress.lineWidth = PROGRESS_WIDTH;[[UIColor redColor] set];[progress stroke];

参数分别为圆心点、半径、绘制起始角度、绘制结束角度、顺时针方向。如果画一个整圆,角度设为0,2pi即可。这里0度对应3点钟方向,我希望绘制从12点方向开始,设置起始角度为-0.5pi即可。结束角度就根据经过的时间和总的时间的比例进行角度计算。有了以上参数也可以算出在当前角度下的圆周上点的坐标,即可以画出那个圆点。


定时器

这里为了绘制看起来更连贯,我选择0.05秒刷新一次界面,而没有参考系统定时器的1秒刷新一次,这样看起来会更舒服。但在显示数字上会遇到1秒的误差,所以我在格式化字符串的时候对剩余时间做了向上去整ceil()的操作,具体差别可以通过改代码来尝试。

m_timer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(setProgress) userInfo:nil repeats:YES];

UIPickerView循环显示

我一直以为iOS的滚轮是支持内容循环显示的,然而并没有看到相关接口,所以有点迷茫。查过资料后发现原来是用了一个技巧,即循环设置非常多的滚轮内容,然后默认选择居中的item,比如设置10000个项,内容是:0,1,2, ..., 97, 98, 99, 0, 1, 2, ..., 97, 98, 99, ...,然后默认显示第5000个条目,这样用户划起来就好像是循环的。因为总的内容很多,用户不会划很多次,所以用户一般不会遇到划到头的情况。于是,我在系统计时器里试了一下,的确是这样的,当我往一个方向划动非常多次后,滚轮还是会到头的。所以这是可行的方法。

//这里可以直接用MAX_ROWS / 2,但下面的计算适合各种情况:取中间位置,取整,再取余根据余数校正起始位置为要显示内容的第一项(即选中居中的 0 的位置)- (void)init {[m_pickerView selectRow:(((NSInteger)((MAX_ROWS / 2) / [m_arrayData count])) * [m_arrayData count]) + (selectedRow % [m_arrayData count]) inComponent:0 animated:NO];}-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{    return MAX_ROWS;}

固定“分钟”单位

系统定时器在选择数字的时候,右边会有一个固定的单位。我依然没有在UIPickerView中找到设置固定单位的接口。如果在-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)componet方法里加上单位,则效果是每一项都会有这个单位。为了解决这个问题,我先尝试了第一种方法,即返回两列滑轮,第二列只有一行:“分钟”,这样显示效果没问题,但第二列是可以拖动的,即有边界弹性效果,而且系统也没有提供关闭弹性效果的接口(btw:UIScrollView里有)。因为这个效果和系统定时器的不一样,所以弃用,不过代码里依然遗留。第二个方案就是直接贴一个Label到适当的位置。简单粗暴,就是位置坐标需要调整到完美显示。不过把它封装成一套控件,往后就可以随意使用了。

参考资料因为chrome没设置同步历史记录,所以这台电脑上没有,改天抽空补上

完整代码可以看:
自定义AlertView用的是开源的项目:

Written with .

转载于:https://www.cnblogs.com/rossoneri/p/4868606.html

你可能感兴趣的文章
代码小思考
查看>>
Unity中的销毁方法
查看>>
ceph删除pool提示(you must first set the mon_allow_pool_delete config option to true)解决办法...
查看>>
2016-7-15(1)使用gulp构建一个项目
查看>>
文件上传案例——客户端和服务端套接字
查看>>
模拟BS服务器
查看>>
Lambda表达式——注重过程的编程思想
查看>>
网络通信和网络编程
查看>>
转换流
查看>>
序列化流
查看>>
线程池
查看>>
Junit单元测试
查看>>
Stream流思想和常用方法
查看>>
Stream流方法引用
查看>>
反射应用和获取Class对象的三种方式
查看>>
Spring框架
查看>>
JSP
查看>>
Session会话技术
查看>>
session案例之验证码
查看>>
数据导出生成word附件使用POI的XWPFTemplate对象
查看>>