美文网首页
谈谈iOS标尺的实现

谈谈iOS标尺的实现

作者: 大神风格化X | 来源:发表于2018-08-31 09:26 被阅读91次

    挺长时间没有撰写技术文章了,今天给大家介绍的虽然不是常用到的标尺demo,但是从这个demo中我们可以学习到别人的绘图是怎么实现的。。。

    和以往一样,首先我要强调的是思路。

    1.我们要考虑标尺中长短线段不一的实现,还有数字的显示.

    先上代码:

    (.h)

    #import

    typedefNS_ENUM(NSUInteger, RulerDirection) {

        RulerDirectionHorizontal,  //横向

        RulerDirectionVertical,    //纵向

    };

    typedefNS_ENUM(NSUInteger, RulerFace) {

        RulerFace_up_left,//横向朝上,纵向朝左

        RulerFace_down_right,//横向朝下,纵向朝右

    };

    typedef struct LineColor {

        CGFloat R;

        CGFloat G;

        CGFloat B;

    } CustomeColor;

    //c 函数构造结构体

    CustomeColorcustomColorMake(CGFloatR,CGFloatG,CGFloatB);

    typedef void(^Handler)(void);

    @interfaceRullerView :UIView

    /**

     长刻度的长度 默认 fit(24)

     */

    @property (nonatomic,assign) float h_height;

    /**

     短刻度的长度 默认 fit(12)

     */

    @property (nonatomic,assign) float m_height;

    /**

     标尺显示的最小值,默认 0

     */

    @property (nonatomic,assign) NSInteger lockMin;

    /**

     标尺显示的最大值,默认 360

     */

    @property (nonatomic,assign) NSInteger lockMax;

    /**

     一个刻度代表的值是多少,默认 1

     */

    @property (nonatomic,assign) NSInteger unitValue;

    /**

     默认横向滚动

     */

    @property (nonatomic,assign) RulerDirection rulerDirection;

    /**

     默认朝上,朝左

     */

    @property (nonatomic,assign) RulerFace rulerFace;

    /**

     是否显示刻度值

     */

    @property (nonatomic,assign)BOOL isShowRulerValue;

    /**

     标尺数字颜色

     */

    @property (nonatomic,strong) UIColor *txtColor;//标尺上数字的颜色

    /**

     标尺线的颜色

     */

    @property (nonatomic) CustomeColor lineColor;//标尺线的颜色

    /**

     指针位置,默认居中

     */

    @property (nonatomic,assign) CGRect pointerFrame;

    /**

     标尺视图的背景颜色 默认白色

     */

    @property(nonatomic,strong)UIColor*rulerBackgroundColor;

    - (void)drawRuler:(Handler)block;

    #pragma 自定义的宏

    //屏幕尺寸

    #define cy_ScreenW [UIScreen mainScreen].bounds.size.width

    #define cy_ScreenH [UIScreen mainScreen].bounds.size.height

    //视图尺寸

    #define cy_selfWidth self.bounds.size.width

    #define cy_selfHeight self.bounds.size.height

    //px宏除2

    #define cy_px(value) (value)/2.0

    //按宽度适配

    #define cy_fit(value) (cy_px(value))*cy_ScreenW/375.0

    // RGB颜色转换(16进制->10进制)

    #define UIColorFromRGB(rgbValue)\

    \

    [UIColor colorWithRed:((float)((rgbValue &0xFF0000) >>16))/255.0\

    green:((float)((rgbValue &0xFF00) >>8))/255.0\

    blue:((float)(rgbValue &0xFF))/255.0\

    alpha:1.0]

    @end

    (.m)

    #import "RullerView.h"

    @interface RullerView()

    {

        float_unitPX;//标尺单位长度

        float_coarseness;//标尺粗

        float_num_height;//数字高度

        float_num_top;//数字头部位置

        float_mark_bottom;//刻度尾部位置

        float_short_mark_top;//短刻度头部位置

        float_long_mark_top;//长刻度头部位置

    }

    @end

    @implementation RullerView

    - (instancetype)initWithFrame:(CGRect)frame {

        self= [superinitWithFrame:frame];

        if(self) {

        }

        return self;

    }

    - (void)start {

        self.backgroundColor = _rulerBackgroundColor?_rulerBackgroundColor:[UIColor whiteColor];

        _unitPX=cy_fit(14);

        _coarseness = cy_fit(1);

        _num_height = cy_fit(24);

        _txtColor = UIColorFromRGB(0xDDDDDD);

        _lineColor = customColorMake(221, 221, 221);

        if (_rulerDirection == RulerDirectionHorizontal) {

            if (_rulerFace == RulerFace_up_left) {

                _mark_bottom=cy_selfHeight/2.0;

                _short_mark_top = _mark_bottom-_m_height;

                _long_mark_top = _mark_bottom-_h_height;

                _num_top=_mark_bottom+cy_fit(10);

    //            _long_mark_top-_num_height-cy_fit(10);

            }else if (_rulerFace == RulerFace_down_right) {

                _mark_bottom=cy_selfHeight/2.0;

                _short_mark_top = _mark_bottom+_m_height;

                _long_mark_top = _mark_bottom+_h_height;

                _num_top = _long_mark_top+_num_height-cy_fit(10);

            }else{

                NSAssert(NO,@"error");

            }

        }else if (_rulerDirection == RulerDirectionVertical) {

            if (_rulerFace == RulerFace_up_left) {

                _mark_bottom=cy_selfWidth/2.0;

                _short_mark_top = _mark_bottom-_m_height;

                _long_mark_top = _mark_bottom-_h_height;

                _num_top = _long_mark_top-_unitPX*8+cy_fit(10);

            }else if (_rulerFace == RulerFace_down_right) {

                _mark_bottom=cy_selfWidth/2.0;

                _short_mark_top = _mark_bottom+_m_height;

                _long_mark_top = _mark_bottom+_h_height;

                _num_top = _long_mark_top-cy_fit(10);

            }else{

                NSAssert(NO,@"error");

            }

        }else{

            NSAssert(NO,@"error");

        }

    }

    - (void)drawRuler:(Handler)block {

        [selfstart];

        if(block) {

            block();

        }

        [self setNeedsDisplay];

    }

    //绘制方法

    - (void)drawRect:(CGRect)rect {

        [superdrawRect:rect];

        CGContextRef context = UIGraphicsGetCurrentContext();

        CGContextSetRGBStrokeColor(context,self.lineColor.R,self.lineColor.G,self.lineColor.B,1.0);

        CGContextSetLineWidth(context, _coarseness);

        //画轴

        CGPointaPoints[2];//X轴

        if (_rulerDirection == RulerDirectionHorizontal) {

            aPoints[0] =CGPointMake(0,_mark_bottom);//起始点

            aPoints[1] =CGPointMake(cy_selfWidth,_mark_bottom);//终点

        }else if (_rulerDirection == RulerDirectionVertical) {

            aPoints[0] =CGPointMake(_mark_bottom,0);//起始点

            aPoints[1] =CGPointMake(_mark_bottom,cy_selfHeight);//终点

        }else{

            NSAssert(NO,@"error");

        }

        CGContextAddLines(context, aPoints,2);//添加线

        CGContextDrawPath(context, kCGPathStroke); //根据坐标绘制路径

        //画刻度

        for (NSInteger i=_lockMin/_unitValue; i<(_lockMax/_unitValue+1); i++) {

            CGContextSetRGBStrokeColor(context,self.lineColor.R,self.lineColor.G,self.lineColor.B,1.0);

            CGContextSetLineWidth(context, _coarseness);

            CGPointaPoints[2];//X轴

            if (_rulerDirection == RulerDirectionHorizontal) {

                aPoints[0] =CGPointMake(_pointerFrame.origin.x+_pointerFrame.size.width/2.0+_unitPX*i, i%10==0?_long_mark_top:_short_mark_top);//起始点

                aPoints[1] =CGPointMake(_pointerFrame.origin.x+_pointerFrame.size.width/2.0+_unitPX*i, _mark_bottom);//终点

            }else if (_rulerDirection == RulerDirectionVertical) {

                aPoints[0] =CGPointMake(i%10==0?_long_mark_top:_short_mark_top,_pointerFrame.origin.y+_pointerFrame.size.height/2.0+_unitPX*i);//起始点

                aPoints[1] =CGPointMake(_mark_bottom,_pointerFrame.origin.y+_pointerFrame.size.height/2.0+_unitPX*i);//终点

            }else{

                NSAssert(NO,@"error");

            }

            CGContextAddLines(context, aPoints,2);//添加线

            CGContextDrawPath(context, kCGPathStroke); //根据坐标绘制路径

            if(_isShowRulerValue&& i%10==0) {

                NSMutableParagraphStyle *textStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];

                textStyle.lineBreakMode = NSLineBreakByWordWrapping;

                textStyle.alignment = NSTextAlignmentCenter;

                UIFont  *font = [UIFont systemFontOfSize:_num_height];

                NSDictionary *attributes = @{NSForegroundColorAttributeName:self.txtColor,NSFontAttributeName:font, NSParagraphStyleAttributeName:textStyle};

                if (_rulerDirection == RulerDirectionHorizontal) {

                    [@(i*_unitValue).stringValue drawInRect:CGRectMake(_pointerFrame.origin.x+_pointerFrame.size.width/2.0+_unitPX*(i-4), _num_top, _unitPX*8, _num_height) withAttributes:attributes];

                }else if (_rulerDirection == RulerDirectionVertical) {

                    [@(i*_unitValue).stringValue drawInRect:CGRectMake(_num_top, _pointerFrame.origin.y+_pointerFrame.size.height/2.0+_unitPX*(i-1), _unitPX*8, _num_height) withAttributes:attributes];

                }else{

                    NSAssert(NO,@"error");

                }

            }

        }

    }

    //c 函数构造结构体

    CustomeColorcustomColorMake(CGFloatR,CGFloatG,CGFloatB) {

        CustomeColorl;l.R= R/255.0;l.G= G/255.0;l.B= B/255.0;returnl;

    }

    @end

    这里面着重强调的两个点:一个是自定义标尺绘图视图类要暴露一个绘图回调block给外面。

    相关文章

      网友评论

          本文标题:谈谈iOS标尺的实现

          本文链接:https://www.haomeiwen.com/subject/lanjwftx.html