• [iOS]圆形进度条及计时功能


    平时用战网安全令的时候很喜欢圆形倒计时的效果,然后简单看了一下Android的圆形进度条,后来又写了一个IOS的。整体界面参照IOS系统的倒计时功能,顺便熟悉了UIPickerView的一些特性的实现方法。完整代码可以看:Github
    其实没什么难度,下面记录几个要点
    本文地址:http://www.cnblogs.com/rossoneri/p/4868606.html

    放个预览图


    画圆

    用的贝塞尔曲线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没设置同步历史记录,所以这台电脑上没有,改天抽空补上
    完整代码可以看:Github
    自定义AlertView用的是开源的项目:Github

    Written with StackEdit.

  • 相关阅读:
    python基础(6)---set、collections介绍
    Vue Router滚动行为 scrollBehavior
    CSS expression属性
    定时器setTimeout实现函数节流
    axios封装
    vue项目结构
    搭建vue项目环境
    javascript参数传递中处理+号
    微信支付 chooseWXPay:fail
    微信支付get_brand_wcpay_request:fail
  • 原文地址:https://www.cnblogs.com/rossoneri/p/4868606.html
Copyright © 2020-2023  润新知