• [控件] CircleView


    CircleView

    效果图:

    源码:

    //
    //  CircleView.h
    //  YXMWeather
    //
    //  Created by XianMingYou on 15/2/17.
    //  Copyright (c) 2015年 XianMingYou. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface CircleView : UIView
    
    /**
     *  线条宽度
     */
    @property (nonatomic)         CGFloat   lineWidth;
    
    /**
     *  线条颜色
     */
    @property (nonatomic, strong) UIColor  *lineColor;
    
    /**
     *  旋转方向
     */
    @property (nonatomic)         BOOL      clockWise;
    
    /**
     *  开始角度
     */
    @property (nonatomic)         CGFloat   startAngle;
    
    /**
     *  初始化view
     */
    - (void)buildView;
    
    /**
     *  做stroke动画
     *
     *  @param value    取值 [0, 1]
     *  @param animated 时候执行动画
     */
    - (void)strokeEnd:(CGFloat)value animated:(BOOL)animated duration:(CGFloat)duration;
    
    @end
    //
    //  CircleView.m
    //  YXMWeather
    //
    //  Created by XianMingYou on 15/2/17.
    //  Copyright (c) 2015年 XianMingYou. All rights reserved.
    //
    
    #import "CircleView.h"
    
    // 将度数转换为弧度
    #define   RADIAN(degrees)  ((M_PI * (degrees))/ 180.f)
    
    // 将弧度转换为度数
    #define   DEGREES(radian)  ((radian) * 180.f / M_PI)
    
    @interface CircleView ()
    
    @property (nonatomic, strong) CAShapeLayer *circleLayer; // 圆形layer
    
    @end
    
    @implementation CircleView
    
    /**
     *  初始化frame值
     *
     *  @param frame 尺寸值
     *
     *  @return 实例对象
     */
    - (instancetype)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
            // 创建出layer
            [self createCircleLayer];
        }
        
        return self;
    }
    
    /**
     *  创建出layer
     */
    - (void)createCircleLayer {
        self.circleLayer       = [CAShapeLayer layer];
        self.circleLayer.frame = self.bounds;
        [self.layer addSublayer:self.circleLayer];
    }
    
    /**
     *  初始化view
     */
    - (void)buildView {
        // 初始化信息
        CGFloat  lineWidth = (self.lineWidth <= 0 ? 1 : self.lineWidth);
        UIColor *lineColor = (self.lineColor == nil ? [UIColor blackColor] : self.lineColor);
        CGSize   size      = self.bounds.size;
        CGFloat  radius    = size.width / 2.f - lineWidth / 2.f; // 设置半径(刚好贴到frame上面去)
        
        // 旋转方向
        BOOL clockWise = self.clockWise;
        CGFloat startAngle = 0;
        CGFloat endAngle   = 0;
        if (clockWise == YES) {
            startAngle = -RADIAN(180 - self.startAngle);
            endAngle   = RADIAN(180 + self.startAngle);
        } else {
            startAngle = RADIAN(180 - self.startAngle);
            endAngle   = -RADIAN(180 + self.startAngle);
        }
        
        // 创建出贝塞尔曲线
        UIBezierPath *circlePath 
            = [UIBezierPath bezierPathWithArcCenter:CGPointMake(size.height / 2.f, size.width / 2.f)
                                             radius:radius
                                         startAngle:startAngle
                                           endAngle:endAngle
                                          clockwise:clockWise];
    
        // 获取path
        self.circleLayer.path = circlePath.CGPath;
        
        // 设置颜色
        self.circleLayer.strokeColor = lineColor.CGColor;
        self.circleLayer.fillColor   = [[UIColor clearColor] CGColor];
        self.circleLayer.lineWidth   = lineWidth;
        self.circleLayer.strokeEnd   = 0.f;
    }
    
    /**
     *  做stroke动画
     *
     *  @param value    取值 [0, 1]
     *  @param animated 时候执行动画
     */
    - (void)strokeEnd:(CGFloat)value animated:(BOOL)animated duration:(CGFloat)duration {
        
        // 过滤掉不合理的值
        if (value <= 0) {
            value = 0;
        } else if (value >= 1) {
            value = 1.f;
        }
        
        if (animated) {
            // 关键帧动画
            CABasicAnimation *basicAnimation = [CABasicAnimation animation];
            basicAnimation.keyPath           = @"strokeEnd";
            basicAnimation.duration          = duration;
            basicAnimation.timingFunction    = 
            [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
            basicAnimation.fromValue         = @(self.circleLayer.strokeEnd);
            basicAnimation.toValue           = @(value);
            
            // 执行动画
            self.circleLayer.strokeEnd = value;
            [self.circleLayer addAnimation:basicAnimation forKey:nil];
        } else {
            // 关闭动画
            [CATransaction setDisableActions:YES];
            self.circleLayer.strokeEnd = value;
        }
    }
    
    @end
  • 相关阅读:
    30 Day Challenge Day 11 | Leetcode 55. Jump Game
    30 Day Challenge Day 11 | Leetcode 11. Container With Most Water
    30 Day Challenge Day 10 | Leetcode 701. Insert into a Binary Search Tree
    30 Day Challenge Day 10 | Leetcode 1. Two Sum
    30 Day Challenge Day 10 | Leetcode 3. Longest Substring Without Repeating Characters
    30 Day Challenge Day 9 | Leetcode 425. Word Squares
    30 Day Challenge Day 8 | Leetcode 200. Number of Islands
    30 Day Challenge Day 7 | Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
    30 Day Challenge Day 7 | Hackerrank: Tree: Huffman Decoding
    30 Day Challenge Day 6 | Leetcode 92. Reverse Linked List II
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/4295461.html
Copyright © 2020-2023  润新知