zoukankan      html  css  js  c++  java
  • 用drawRect的方式实现一个尺子

    用drawRect的方式实现了一个尺子选择器,demo在这里:https://github.com/Phelthas/LXMRulerView
    效果如图:
     
    如果不考虑复用的问题,我感觉最简单的实现方式其实是让美术做一张尺子的图片,放到scrollView上就可以了,
    数值可以根据scrollview的contentOffset来计算。
    如果考虑复用的问题,还是用代码写来的方便,封装一些属性,就可以实现很多不同的样式。所以就有了这个LXMRulerView~
     
    实现方案:
    目前用的是一个比较笨的实现方案,就是用drawRect的方式画了一个尺子,然后把这个view放到scrollview上,然后用scrollview的contentOffset来计算数值。
    有看到资料说用drawRect的方式会比较占内存,用CALayer实现会好很多,这个我还没有试,但目前来看demo里面内存占用都很小,有空试一下layer的实现方式吧~
    为什么说这个方案比较笨呢?因为这里面其实是完完全全画了一个完整的尺子,没有复用任何资源,所以理论上如果尺子很长很长的话,还是会很消耗内存的;
    考虑到尺子也是不断重复的外观,只有数字不一样,所以理论上用一个横向的collectionView来实现会更好一些,这个有空实践一下看看效果怎么样吧~
     
     
    需要注意的地方:
    1,对autoLayout的支持和从xib初始化的支持
    drawRect是按bounds来画图的,而且默认情况下drawRect方法只会调用一次。
    所以如果从xib初始化,且初始化时的view大小与最终显示的view大小不同的话,drawRect是按最初初始化的大小来绘制的,不会随着autoLayout调整大小,
    所以这里没有什么好的办法,只能在layoutSubview中手动调整改view的大小。
    但仅仅调整view大小还不够,画好的图默认不会重新绘制,UIView有一个contentMode属性,需将其设置为UIViewContentModeRedraw,
    效果是在view的bounds有变化时,会重新调用drawRect方法。
     
    2,整数吸附效果
    在scrollviewDidScroll的方法中调整contentOffset来使其停留在整数的位置上的方法太low了!!!会使动画效果看起来很不连贯
    怎么解决呢?
    就是用
    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inoutCGPoint *)targetContentOffset
    这个方法,这也是系统提供的delegate方法,所以可以放心用,效果就是可以让scrollview刚好停留在targetContentOffset的位置,所以只需要在这个方法中计算出指定的位置就可以了~
     
    3,数值变化的回调
    为了简单易用,数值变化的回调方法是用block的方式。
    在用的时候,需要注意一下循环引用的问题,所以block中还是用weakSelf安全一点
     
    4,为了保证滑动位置的准确度,尺子最大最小值和间距都只支持整型,不支持浮点数~~等想到好解决办法支持~
     
     
    2016年9月28日更新
    经测试发现,如果尺子比较长的话,用drawRect的方式确实占用了很大的内存,而且尺子越长,占用的内存越大,所以改用CALayer的方式实现,可以有效的减少内存;
    加入了accuracy属性,表示一个刻度代表的值,比如accuracy为0.1,那么一个刻度表示0.1; 
     
    2017年3月25日更新
    因为在tableView的cell中使用了这个rulerView,发现每次reloadData的时候界面都会卡很久,想来估计还是尺子在绘制的时候卡住了。。。
    被逼无奈,还是只能用collectionView重构一下了,也就是最开始写的时候就想到但是没有实践的方式。。。
    重构效果还不错,现在就算是在tableViewCell里,也能瞬间绘制完成了;
    加入了defaultValue属性,让尺子可以在绘制完成时直接显示设定的值:
    这里稍微有点坑需要注意一下,因为scrollview在调整contentInset的时候,触发ScrollViewDidScroll方法,所以要注意设置初始值的时机,目前我是写在layoutSubView方法里面的;
    pod已经更新到2.1.0版本,欢迎使用~ 
     
    目前还在持续更新中,有什么问题欢迎讨论~
     
     
  • 相关阅读:
    为什么 执行typeof null时会返回字符串“object”?
    vue init webpack-simple 模板中全局引入Jquery正确使用方法 可保jQuery插件正常使用
    掘金文章图片弹出放大缩小效果
    神奇的CSS3混合模式转载
    随笔
    vue-cli 项目中绝对路径引用的相关资源 npm run build 后 打开页面报404错误
    软件工程期末展示材料——RUC自习助手
    RUC自习助手_用户手册
    【声明】RUC自习助手APP(Android版)已上线,可下载
    RUC自习助手_测试文档
  • 原文地址:https://www.cnblogs.com/Phelthas/p/5697166.html
Copyright © 2011-2022 走看看