iOS可複用控件之錶盤

GitHub地址:https://github.com/runThor/HTDial

效果:



實現:

// 實際應用中,整個區域經常需要分爲偏低區域、適中區域、偏高區域等不同的劃分區域,要用不同的顏色標識,這裏我們默認劃分低、中、高三個區域,所以需要兩個區域的間隔值

//  HTDialView.h


#import <UIKit/UIKit.h>


@interface HTDialView : UIView


@property (nonatomic,assign)CGFloat minValue;  // 錶盤下限值

@property (nonatomic,assign)CGFloat maxValue;  // 錶盤上限值

@property (nonatomic,assign)CGFloat firstSeparationValue;  // 第一個區域間隔值

@property (nonatomic,assign)CGFloat secondSeparationValue;  // 第二個區域間隔值


// 設置指針指向的值

- (void)pointValue:(CGFloat)value;


@end



//  HTDialView.m


#import "HTDialView.h"


@interface HTDialView ()


@property (nonatomic,strong)UIView *pointerView;  // 指針


@end



@implementation HTDialView


- (void)drawRect:(CGRect)rect {

    // 繪製劃分區域

    [self drawAreas];

    

}


- (instancetype)initWithFrame:(CGRect)frame {

    

    if (self = [super initWithFrame:frame]) {

        // 初始化視圖

        [self configViews];

        

    }

    

    return self;

}


// 初始化視圖方法

- (void)configViews {

    

    // 錶盤輪廓

    UIImageView *dialBgImgView = [[UIImageView allocinitWithFrame:self.bounds];

    dialBgImgView.image = [UIImage imageNamed:@"dial_bg"];

    [self addSubview:dialBgImgView];

    

    // 初始化指針

    self.pointerView = [[UIView alloc]initWithFrame:CGRectMake(0,0,3,80)];

    [self.pointerView setCenter:dialBgImgView.center];

    self.pointerView.backgroundColor = [UIColor yellowColor];

    self.pointerView.layer.anchorPoint = CGPointMake(0.5,0.25);  // 指針旋轉的支點

    self.pointerView.layer.masksToBounds = YES;

    // 優化渲染性能

    self.pointerView.layer.shouldRasterize = YES;  

    self.pointerView.layer.rasterizationScale = [UIScreen mainScreen].scale;

    [self addSubview:self.pointerView];

}


// 繪製劃分區域及顏色

- (void)drawAreas {

    

    if (self.minValue ==self.maxValue) {

        

        return;

    

    }

    

    CGContextRef contextRef =UIGraphicsGetCurrentContext();

    CGSize viewSize =self.bounds.size;

    CGPoint center =CGPointMake(viewSize.width/2, viewSize.height/2);

    CGFloat radius = viewSize.width/2;

    

    // 繪製低值區域

    CGFloat lowAreaAngle = (self.firstSeparationValue -self.minValue)/(self.maxValue -self.minValue) * (1.5 *M_PI);

    

    CGContextBeginPath(contextRef);

    CGContextMoveToPoint(contextRef, center.x, center.y);

    CGContextAddArc(contextRef, center.x, center.y, radius,M_PI_2,M_PI_2 + lowAreaAngle,0);

    CGContextSetFillColorWithColor(contextRef, [UIColor colorWithRed:0/255.0 green:102.0/255.0 blue:255.0/255.0 alpha:1.0].CGColor);

    CGContextFillPath(contextRef);

    

    // 繪製中值區域

    CGFloat middleAreaAngle = (self.secondSeparationValue -self.firstSeparationValue)/(self.maxValue -self.minValue) * (1.5 *M_PI);

    

    CGContextBeginPath(contextRef);

    CGContextMoveToPoint(contextRef, center.x, center.y);

    CGContextAddArc(contextRef, center.x, center.y, radius,M_PI_2 + lowAreaAngle, M_PI_2 + lowAreaAngle + middleAreaAngle,0);

    CGContextSetFillColorWithColor(contextRef, [UIColor colorWithRed:13/255.0 green:142/255.0 blue:0/255.0 alpha:1.0].CGColor);

    CGContextFillPath(contextRef);

    

    // 繪製高值區域

    CGContextBeginPath(contextRef);

    CGContextMoveToPoint(contextRef, center.x, center.y);

    CGContextAddArc(contextRef, center.x, center.y, radius,M_PI_2 + lowAreaAngle + middleAreaAngle,M_PI *2,0);

    CGContextSetFillColorWithColor(contextRef, [UIColor colorWithRed:250/255.0 green:47/255.0 blue:47/255.0 alpha:1.0].CGColor);

    CGContextFillPath(contextRef);

    

    // 繪製遮罩圓,只展示環形區域

    CGContextBeginPath(contextRef);

    CGContextMoveToPoint(contextRef, center.x, center.y);

    CGContextAddArc(contextRef, center.x, center.y, radius *0.8,0,M_PI *2,0);

    CGContextSetFillColorWithColor(contextRef,self.backgroundColor.CGColor);

    CGContextFillPath(contextRef);

    

}


// 設置指針指向的值

- (void)pointValue:(CGFloat)value {

    

    if (self.minValue ==self.maxValue || value <self.minValue || value >self.maxValue) {

        

        return;

        

    }

    

    // 指針旋轉動畫

    [UIView animateWithDuration:1.0 animations:^{

        

        CGFloat angle = ((value -self.minValue)/(self.maxValue -self.minValue)) * (M_PI *1.5);

        

        if (angle >M_PI) {

            

            // 旋轉角度大於180度,需要分兩步旋轉,否則會逆向旋轉

            self.pointerView.transform =CGAffineTransformMakeRotation(M_PI);

            self.pointerView.transform =CGAffineTransformMakeRotation(angle);

            

        } else {

            

            // 旋轉角度小於等於180度,旋轉一次即可

            self.pointerView.transform =CGAffineTransformMakeRotation(angle);

        }

    }];

}


使用:

//  ViewController.m


#import "ViewController.h"

#import "HTDialView.h"


@interface ViewController ()


@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    

    self.view.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];

    

    HTDialView *dialView = [[HTDialView alloc] initWithFrame:CGRectMake(0,0, 200,200)];

    dialView.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];

    [dialView setCenter:CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/2)];

    dialView.minValue =0;  // 下限

    dialView.maxValue =100;  // 上限

    dialView.firstSeparationValue =30;  // 第一間隔值

    dialView.secondSeparationValue =60;  // 第二間隔值

    [dialView pointValue:50];  // 指針指向50

    [self.view addSubview:dialView];

}




發佈了39 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章