zoukankan      html  css  js  c++  java
  • [控件] 动态实时设置CAShapeLayer贝塞尔曲线的坐标点

    动态实时设置CAShapeLayer贝塞尔曲线的坐标点

    效果图:

    源码:

    PathDirectionView.h 与 PathDirectionView.m

    //
    //  PathDirectionView.h
    //  Path
    //
    //  Created by XianMingYou on 15/2/27.
    //  Copyright (c) 2015年 XianMingYou. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    #import "UIView+SetRect.h"
    
    @interface PathDirectionView : UIView
    
    /**
     *  起始点在右边
     */
    @property (nonatomic) BOOL  startPointAtRight;
    
    /**
     *  根据百分比显示
     *
     *  @param percent 百分比
     */
    - (void)showPercent:(CGFloat)percent;
    
    @end
    //
    //  PathDirectionView.m
    //  Path
    //
    //  Created by XianMingYou on 15/2/27.
    //  Copyright (c) 2015年 XianMingYou. All rights reserved.
    //
    
    #import "PathDirectionView.h"
    
    @interface PathDirectionView () {
        CAShapeLayer  *_shapeLayer;
    }
    
    @end
    
    @implementation PathDirectionView
    
    /**
     *  修改当前view的backupLayer为CAGradientLayer
     *
     *  @return CAGradientLayer类名字
     */
    + (Class)layerClass {
        return [CAShapeLayer class];
    }
    
    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            _shapeLayer             = (CAShapeLayer *)self.layer;
            _shapeLayer.fillColor   = [[UIColor clearColor] CGColor];
            _shapeLayer.strokeColor = [[UIColor redColor] CGColor];
            _shapeLayer.lineWidth   = 1.f;
            _shapeLayer.strokeEnd   = 0.f;
            _shapeLayer.opacity     = 0.f;
            _shapeLayer.path        = [self createPathWithHeight:0];
        }
        return self;
    }
    
    /**
     *  创建出贝塞尔曲线
     *
     *  @param height 高度
     *
     *  @return 贝塞尔曲线
     */
    - (CGPathRef)createPathWithHeight:(CGFloat)height {
        UIBezierPath *bezierPath = UIBezierPath.bezierPath;
        
        CGPoint startPoint = CGPointZero;
        CGPoint endPoint   = CGPointZero;
        if (self.startPointAtRight == NO) {
            startPoint = CGPointMake(self.width, height);
            endPoint   = CGPointZero;
        } else {
            startPoint = CGPointMake(0, height);
            endPoint   = CGPointMake(self.width, 0);
        }
        
        [bezierPath moveToPoint:startPoint];
        [bezierPath addLineToPoint:endPoint];
        
        return bezierPath.CGPath;
    }
    
    
    - (void)showPercent:(CGFloat)percent {
        
        if (percent < 0) {
            _shapeLayer.path      = [self createPathWithHeight:0];
            _shapeLayer.strokeEnd = 0;
            _shapeLayer.opacity   = 0;
        } else if (percent >= 0 && percent <= 0.5f) { // [0, 0.5]
            _shapeLayer.path      = [self createPathWithHeight:0];
            _shapeLayer.strokeEnd = percent * 2.f;
            _shapeLayer.opacity   = percent * 2.f;
        } else if (percent <= 1.f) { // (0.5, 1]
            CGFloat currentPercent = percent - 0.5f;
            _shapeLayer.path      = [self createPathWithHeight:currentPercent * self.height * 2];
            _shapeLayer.strokeEnd = 1.f;
            _shapeLayer.opacity   = 1.f;
        } else { // (1, +无穷大)
            _shapeLayer.path      = [self createPathWithHeight:self.height];
            _shapeLayer.strokeEnd = 1.f;
            _shapeLayer.opacity   = 1.f;
        }
    }
    
    @end

    ShowDownView.h 与 ShowDownView.m

    //
    //  ShowDownView.h
    //  Path
    //
    //  Created by XianMingYou on 15/2/27.
    //  Copyright (c) 2015年 XianMingYou. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    #import "PathDirectionView.h"
    
    @interface ShowDownView : UIView
    
    - (void)showPercent:(CGFloat)percent;
    
    @end
    //
    //  ShowDownView.m
    //  Path
    //
    //  Created by XianMingYou on 15/2/27.
    //  Copyright (c) 2015年 XianMingYou. All rights reserved.
    //
    
    #import "ShowDownView.h"
    
    @interface ShowDownView ()
    
    @property (nonatomic, strong) PathDirectionView *leftView;
    @property (nonatomic, strong) PathDirectionView *rightView;
    
    @end
    
    @implementation ShowDownView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            CGFloat width  = frame.size.width / 2.f;
            CGFloat height = frame.size.height;
            
            CGRect leftRect  = CGRectMake(0, 0, width, height);
            CGRect rightRect = CGRectMake(width, 0, width, height);
            
            self.leftView  = [[PathDirectionView alloc] initWithFrame:leftRect];
            self.rightView = [[PathDirectionView alloc] initWithFrame:rightRect];
            self.rightView.startPointAtRight = YES;
            [self addSubview:self.leftView];
            [self addSubview:self.rightView];
        }
        return self;
    }
    
    - (void)showPercent:(CGFloat)percent {
        [self.leftView showPercent:percent];
        [self.rightView showPercent:percent];
    }
    
    @end

    核心原理:

    1. 即时的根据值的变化重新生成path值并赋值给CAShapeLayer

    2. 即时的根据值得变化设定strokeEnd值

  • 相关阅读:
    在Visual Studio 2019中配置OpenCV环境
    Java中的垃圾回收
    线程池
    Java中锁优化
    二叉树的几种遍历
    java中Comparator的用法(排序、分组)
    java8 stream
    Java后台生成二维码并上传到阿里云OSS
    代码生成器的成长过程
    软件的军工六性
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/4304480.html
Copyright © 2011-2022 走看看