無比迅速敏捷地開發iOS超精美控件

 目錄

    前言html

    設計git

    編碼github

    PaintCodeswift

 

前言

 

自從人生第一篇博客《iOS中的預編譯指令的初步探究》問世以來 瀏覽量居然達到了360多,(路過的大神勿笑!)這些瀏覽量使我興奮異常但又令我黯然神傷,爲什麼我會眼裏常含淚水?由於國人伸手黨達90%!!!區區只有可憐的三個評論,可憐的三個評論~ 沒有鼓勵~ 沒有鮮花~ 也沒有謾罵~ 可是我不哭 由於賤人會笑!我深信:xcode

 

一日伸手黨,bug終身隨!安全

很久沒打籃球了,「教練,我想打籃球」。服務器

此次的東西標題爲《無比迅速敏捷地開發iOS超精美控件》!就問你怕不怕!!本人深惡痛絕標題黨丫的,因此今天我就絕對會展現一些奇淫巧技!帥氣而且超快的擼出一個iOS精美控件!別說我坑你?app

上圖1async

 

這個我叫它DDClock,全部view都使用Quartz 2D繪製,建立後自動與當前系統對時同步,漂亮、精緻、優雅…… (若是你看到這裏,你說不漂亮、不精緻、不優雅,那麼請你出去,我擔憂我會下手太重,呵呵),想知道怎麼弄得?別急!讓博主帶你手拿菜刀砍電線,一路火光加閃電!!!工具

 

設計

 

在工程界有一個說法:

設計的優秀與否,是致使這個產品成敗的關鍵。

 

好吧設計先行!想好了再動手!想好了再動手在生活中是很重要,好比小學生和初中生是怎麼區分的?區別就是在LOL中他們對技能的施放是否進行周密的思考,因此一些選手一我的直接衝進人堆裏,技能啪啪一甩,而後就掛了——小學生!因此嘛,作事情前養成思考的習慣,是脫離小學生羣體的重要手段哦~

 

前面說到一點,DDClock建立後須要自動與當前系統對時同步;因此

一、咱們不妨讓DDClock繼承UIView,而後重載 

-(void)drawRect:(CGRect)rect

 

方法,在這個方法中帥氣的畫出那個時鐘全部細節!咱們的決心是堅定不使用人民的一張圖片!;

二、而後分析整個DDClock只有指針(時分秒針)和指示上下午的AM、PM會動!因此咱們要把這些個東西射成變量!關於指針的運動,咱們可使用定時器,每秒都和系統對時;

三、咱們還要支持主題的切換,那就給DDClock定義一個枚舉咯;

四、而後就這樣

五、而後就這樣這樣

……

哈~ 在咱們精細的設計中,這個DDClock的產品形態居然出乎的飽滿,俗話說的好,打鐵要趁熱,豆腐趁熱吃。咱們立刻祭出殺器XCode!!我知道你如今已經興奮了

 

編碼

咱們就新建一個項目 叫作DDClockDemo吧,用來測試待會咱們設計的DDClock。

而後咱們就在項目中新建一個Group(文件夾)吧 ,就命名成DDClock嘛~

再而後嘛,咱們就在DDClock的文件夾下新建一個OC對象吧(Cocoa Touch Class)取名字DDClock,讓它繼承UIView

Nice!!來看看咱們的工程目錄結構 圖2

 

 

好!咱們要開始寫代碼咯

DDClock.h

 

//
//  DDClock.h
//  Created by David on 15/1/26.
//  博客:http://www.cnblogs.com/daiweilai/
//  github:https://github.com/daiweilai/
//  Copyright (c) 2015年 DavidDay. All rights reserved.
// 

#import <UIKit/UIKit.h>
#define DDClockSize 200 //默認時鐘的長寬都爲200
#if ! __has_feature(objc_arc)
#error "須要開啓ARC"
#endif

@protocol DDLockDelegate 

@optional
-(UIColor*)rimColor;
-(UIColor*)markColor;
-(UIColor*)faceColor;
-(UIColor*)fontColor;
-(UIColor*)secondHandColor;
-(UIColor*)hourAndMinuteHandColor;

@end


@interface DDClock : UIView

@property (weak, nonatomic) id delegate;

typedef NS_ENUM(NSUInteger, DDClockTheme) { //弄一個枚舉類型用來更改主題
    DDClockThemeDefault = 0,
    DDClockThemeDark,
    DDClockThemeModerm
};

//DDClock的構造方法 delegate:代理
-(instancetype)initWithDelegate:(id)delegate frame:(CGRect)frame;
///DDClock的構造方法 theme:主題 
-(instancetype)initWithTheme:(DDClockTheme)theme frame:(CGRect)frame;

@end

DDClock.m

 

//
//  DDClock.h
//  Created by David on 15/1/26.
//  博客:http://www.cnblogs.com/daiweilai/
//  github:https://github.com/daiweilai/
//  Copyright (c) 2015年 DavidDay. All rights reserved.
//

#import "DDClock.h"

@interface DDClock(){
    //// 聲明顏色
    UIColor* rimColor;
    UIColor* faceColor;
    UIColor* markColor;
    UIColor* secondHandColor;
    UIColor* fontColor;
    UIColor* hourAndMinuteHandColor;
    DDClockTheme _theme;
    float _scale;
    CGPoint _centerPoint;
}
@end


@implementation DDClock


-(instancetype)initWithDelegate:(id)delegate frame:(CGRect)frame{
    //防止用戶在構建的時候傳入的height和widt不同 由於時鐘是圓的因此強制把他們變成長寬同樣
    CGFloat size = frame.size.height>frame.size.width?frame.size.height:frame.size.width;
    CGRect realRect = CGRectMake(frame.origin.x, frame.origin.y, size, size);
    self = [self initWithFrame:realRect];
    if (self) {
        _scale = realRect.size.height / DDClockSize; //放大縮小的比例係數
        _centerPoint = CGPointMake(size/2, size/2); //中心點
        //先使用默認的顏色初始化 防止用戶沒有調用delegate方法
        rimColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
        faceColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1];
        markColor = [UIColor colorWithRed:  160.0/255.0 green: 160.0/255.0 blue: 160.0/255.0 alpha: 1];
        secondHandColor = [UIColor colorWithRed: 86.0/255.0 green: 232.0/255.0 blue: 157.0/255.0 alpha: 1];
        fontColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
        hourAndMinuteHandColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];

		//判斷用戶是否使用了delegate的方法
        if ([delegate respondsToSelector:NSSelectorFromString(@"rimColor")]) {
            rimColor = [delegate rimColor];
        }
        if ([delegate respondsToSelector:NSSelectorFromString(@"faceColor")]) {
            faceColor = [delegate faceColor];
        }
        if ([delegate respondsToSelector:NSSelectorFromString(@"markColor")]) {
            markColor = [delegate markColor];
        }
        if ([delegate respondsToSelector:NSSelectorFromString(@"fontColor")]) {
            fontColor = [delegate fontColor];
        }
        if ([delegate respondsToSelector:NSSelectorFromString(@"hourAndMinuteHandColor")]) {
            hourAndMinuteHandColor = [delegate hourAndMinuteHandColor];
        }
        if ([delegate respondsToSelector:NSSelectorFromString(@"secondHandColor")]) {
            secondHandColor = [delegate secondHandColor];
        }
		
		//秒針使用圖片畫出來
        UIImage *img = [self drawSecondHandWithColor:secondHandColor scale:_scale frameSize:CGSizeMake(size, size) currentAngle:[self secondAngleFromDate:[NSDate new]]];
        UIImageView *imgV = [[UIImageView alloc] initWithImage:img];
        imgV.frame = CGRectMake(0 , 0, size, size);
        [self addSubview:imgV];
        
        //1.建立動畫並指定動畫屬性
        CABasicAnimation *basicAnimation=[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
        
        //2.設置動畫屬性初始值、結束值
        //    basicAnimation.fromValue=[NSNumber numberWithInt:M_PI_2];//
        basicAnimation.toValue=[NSNumber numberWithFloat:2*M_PI];
        
        //設置其餘動畫屬性
        basicAnimation.duration=60.0;//60秒轉一圈
        basicAnimation.autoreverses=false;//旋轉後再旋轉到原來的位置
        basicAnimation.repeatCount = CGFLOAT_MAX;//無限循環的執行動畫
        
        imgV.layer.anchorPoint = CGPointMake(0.5, 0.5);//設置秒針的旋轉中心 就是這個view的中心!
        
        
        //4.添加動畫到圖層,注意key至關於給動畫進行命名,之後得到該動畫時可使用此名稱獲取
        [imgV.layer addAnimation:basicAnimation forKey:@"Rotation"];
        
        
        
        //當這個DDClock被建立出來的時候,就新建一個定時器,1分鐘執行一次「onTimer」方法 其實這裏作是不夠好的 由於這樣不能確保秒針走到12的時候更新 時針和分針 要想解決也很容易 最近生病 難受 不想解決了~~
        [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
    }
    self.backgroundColor = [UIColor clearColor];
    return self;

}


///構造方法 使用默認主題
-(instancetype)initWithTheme:(DDClockTheme)theme frame:(CGRect)frame{
    //防止用戶在構建的時候傳入的height和widt不同 由於時鐘是圓的因此強制把他們變成同樣
    CGFloat size = frame.size.height>frame.size.width?frame.size.height:frame.size.width;
    CGRect realRect = CGRectMake(frame.origin.x, frame.origin.y, size, size);
    self = [self initWithFrame:realRect];
    if (self) {
        _theme = theme;
        _scale = realRect.size.height / DDClockSize;
        _centerPoint = CGPointMake(size/2, size/2);
        
        switch (theme) { //根據主題繪製不一樣的顏色
            case DDClockThemeDefault:
                rimColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
                faceColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1];
                markColor = [UIColor colorWithRed:  160.0/255.0 green: 160.0/255.0 blue: 160.0/255.0 alpha: 1];
                secondHandColor = [UIColor colorWithRed: 86.0/255.0 green: 232.0/255.0 blue: 157.0/255.0 alpha: 1];
                fontColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
                hourAndMinuteHandColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
                break;
                
            case DDClockThemeDark:
                rimColor = [UIColor colorWithRed: 66.0/255 green: 66.0/255 blue: 66.0/255 alpha: 1];
                faceColor = [UIColor colorWithRed: 66.0/255 green: 66.0/255 blue: 66.0/255 alpha: 1];
                markColor = [UIColor colorWithRed:  1 green: 1 blue: 1 alpha: 1];
                secondHandColor = [UIColor colorWithRed: 32.0/255.0 green: 250.0/255.0 blue: 200.0/255.0 alpha: 1];
                fontColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1];
                hourAndMinuteHandColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1];
                break;
                
            case DDClockThemeModerm:
                rimColor = [UIColor colorWithRed: 60.0/255 green: 90.0/255 blue: 110.0/255 alpha: 1];
                faceColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1];
                markColor = [UIColor colorWithRed:  160.0/255.0 green: 160.0/255.0 blue: 160.0/255.0 alpha: 1];
                secondHandColor = [UIColor colorWithRed: 210.0/255.0 green: 0 blue: 10.0/255.0 alpha: 1];
                fontColor = [UIColor colorWithRed: 210.0/255.0 green: 0 blue: 10.0/255.0 alpha: 1];
                hourAndMinuteHandColor = [UIColor colorWithRed: 60.0/255 green: 90.0/255 blue: 110.0/255 alpha: 1];
                break;
            default:
                rimColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
                faceColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1];
                markColor = [UIColor colorWithRed:  160.0/255.0 green: 160.0/255.0 blue: 160.0/255.0 alpha: 1];
                secondHandColor = [UIColor colorWithRed: 86.0/255.0 green: 232.0/255.0 blue: 157.0/255.0 alpha: 1];
                fontColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
                hourAndMinuteHandColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
                break;
        }
        
        if ([_delegate rimColor]) {
            rimColor = [_delegate rimColor];
        }
        if ([_delegate faceColor]) {
           faceColor = [_delegate faceColor];
        }
        if ([_delegate markColor]) {
            markColor = [_delegate markColor];
        }
        if ([_delegate fontColor]) {
            fontColor = [_delegate fontColor];
        }
        if ([_delegate faceColor]) {
            faceColor = [_delegate faceColor];
        }
        if ([_delegate hourAndMinuteHandColor]) {
            hourAndMinuteHandColor = [_delegate hourAndMinuteHandColor];
        }
        if ([_delegate secondHandColor]) {
            secondHandColor = [_delegate secondHandColor];
        }
        
        
        
        UIImage *img = [self drawSecondHandWithColor:secondHandColor scale:_scale frameSize:CGSizeMake(size, size) currentAngle:[self secondAngleFromDate:[NSDate new]]];
        UIImageView *imgV = [[UIImageView alloc] initWithImage:img];
        imgV.frame = CGRectMake(0 , 0, size, size);
        [self addSubview:imgV];
        
        //1.建立動畫並指定動畫屬性
        CABasicAnimation *basicAnimation=[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
        
        //2.設置動畫屬性初始值、結束值
        //    basicAnimation.fromValue=[NSNumber numberWithInt:M_PI_2];
        basicAnimation.toValue=[NSNumber numberWithFloat:2*M_PI];
        
        //設置其餘動畫屬性
        basicAnimation.duration=60.0;
        basicAnimation.autoreverses=false;//旋轉後再旋轉到原來的位置
        basicAnimation.repeatCount = CGFLOAT_MAX;
        
        imgV.layer.anchorPoint = CGPointMake(0.5, 0.5);
        
        
        //4.添加動畫到圖層,注意key至關於給動畫進行命名,之後得到該動畫時可使用此名稱獲取
        [imgV.layer addAnimation:basicAnimation forKey:@"Rotation"];

        
        
        //當這個View被建立出來的時候,就新建一個定時器,1分鐘執行一次「onTimer」方法
        [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
    }
    self.backgroundColor = [UIColor clearColor];
    return self;
}

//每秒鐘刷新視圖一次
-(void)onTimer{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self setNeedsDisplay];//這個方法調用後就會刷新這個View
    });
}

//View刷新這個方法就被調用,就會從新畫出這個View
-(void)drawRect:(CGRect)rect{
    [super drawRect:rect];
    //獲取當前的時間進行View的繪製
    [self drawDDClockWithScale:_scale centerPoint:_centerPoint currentDate:[NSDate new]];


}

////畫出秒針
-(UIImage*)drawSecondHandWithColor:(UIColor*)color scale:(CGFloat)scale frameSize:(CGSize)size currentAngle:(float)currentAngle{
    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    //// secondHand Drawing
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, size.height/2, size.height/2);
    CGContextRotateCTM(context, (currentAngle - 90) * M_PI / 180);
    CGContextScaleCTM(context, scale, scale);
    
    UIBezierPath* secondHandPath = UIBezierPath.bezierPath;
    [secondHandPath moveToPoint: CGPointMake(4.96, -4.87)];
    [secondHandPath addCurveToPoint: CGPointMake(6.93, -0.92) controlPoint1: CGPointMake(6.07, -3.76) controlPoint2: CGPointMake(6.73, -2.37)];
    [secondHandPath addLineToPoint: CGPointMake(66.01, -0.92)];
    [secondHandPath addLineToPoint: CGPointMake(66.01, 0.08)];
    [secondHandPath addLineToPoint: CGPointMake(7.01, 0.08)];
    [secondHandPath addCurveToPoint: CGPointMake(4.96, 5.03) controlPoint1: CGPointMake(7.01, 1.87) controlPoint2: CGPointMake(6.32, 3.66)];
    [secondHandPath addCurveToPoint: CGPointMake(-4.94, 5.03) controlPoint1: CGPointMake(2.22, 7.76) controlPoint2: CGPointMake(-2.21, 7.76)];
    [secondHandPath addCurveToPoint: CGPointMake(-4.94, -4.87) controlPoint1: CGPointMake(-7.68, 2.29) controlPoint2: CGPointMake(-7.68, -2.14)];
    [secondHandPath addCurveToPoint: CGPointMake(4.96, -4.87) controlPoint1: CGPointMake(-2.21, -7.61) controlPoint2: CGPointMake(2.22, -7.61)];
    [secondHandPath closePath];
    [color setFill];
    [secondHandPath fill];
    CGContextRestoreGState(context);
    UIImage *img = [UIImage new];
    img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}


///把當前的時間轉換爲時針、分針、角度
-(NSArray*)HourAndMinuteAngleFromDate:(NSDate*)date{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"HH"];//強制24小時格式
    float hourf = [[formatter stringFromDate:date] floatValue];
    [formatter setDateFormat:@"mm"];
    float minutef = [[formatter stringFromDate:date] floatValue];
    if (hourf > 12) {//大於24小時咱們就減去12小時嘛 比較好算角度呀
        hourf = (hourf - 12)*30 + 30*(minutef/60); //一小時30°
    }else{
        hourf = hourf*30 + 30*(minutef/60);
    }
    minutef = minutef*6;//一分鐘6°
    NSNumber *hour =  [[NSNumber alloc] initWithInt:hourf];
    NSNumber *minute = [[NSNumber alloc] initWithInt:minutef];
    NSArray *arr = [[NSArray alloc] initWithObjects:hour,minute, nil];
    return arr;
}

//由於秒針的實時性 因此單獨算出當前秒針的角度
-(float)secondAngleFromDate:(NSDate*)date{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"ss"];
    float secondf = [[formatter stringFromDate:date] floatValue];
    secondf = secondf*6;//一分鐘6°
    return secondf;
}

//繪製圖形的主要方法
- (void)drawDDClockWithScale: (CGFloat)scale centerPoint:(CGPoint)centerPoint currentDate:(NSDate*)currentDate;
{
    NSArray *arr = [self HourAndMinuteAngleFromDate:currentDate];
    NSNumber *hourAngle = (NSNumber*)[arr objectAtIndex:0];
    NSNumber *minuteAngle = (NSNumber*)[arr objectAtIndex:1];
    
    
    
    //獲取繪圖上下文
    CGContextRef context = UIGraphicsGetCurrentContext();

    //// 畫出邊框
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextScaleCTM(context, scale, scale);
    
    UIBezierPath* rimPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(-100, -100, 200, 200)];
    [rimColor setFill];
    [rimPath fill];
    
    CGContextRestoreGState(context);
    
    
    //// 畫出鐘表盤
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextScaleCTM(context, scale, scale);
    
    UIBezierPath* facePath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(-92.99, -92.92, 186, 186)];
    [faceColor setFill];
    [facePath fill];
    
    CGContextRestoreGState(context);
    
    
    //// 上午下午時間的判斷
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextScaleCTM(context, scale, scale);
    
    CGRect aMPMRect = CGRectMake(-15.99, -42.92, 32, 18);
    NSMutableParagraphStyle* aMPMStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
    aMPMStyle.alignment = NSTextAlignmentCenter;
    
    NSDictionary* aMPMFontAttributes = @{NSFontAttributeName: [UIFont fontWithName: @"Helvetica-Bold" size: 15], NSForegroundColorAttributeName: fontColor, NSParagraphStyleAttributeName: aMPMStyle};
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"HH"];//強制24小時格式
    float hourf = [[formatter stringFromDate:currentDate] floatValue];//爲了節省系統資源 延遲一分鐘纔會更新 由於這個方法是一分鐘 調用一次的
    NSString *str = hourf<12?@"AM":@"PM";
    [str drawInRect: aMPMRect withAttributes: aMPMFontAttributes];
    
    CGContextRestoreGState(context);
    
    
    //// 畫出時針
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextRotateCTM(context, [hourAngle floatValue] * M_PI / 180);
    CGContextScaleCTM(context, scale, scale);
    
    UIBezierPath* hourHandPath = [UIBezierPath bezierPathWithRect: CGRectMake(-4.99, -52.46, 10, 43.54)];
    [hourAndMinuteHandColor setFill];
    [hourHandPath fill];
    
    CGContextRestoreGState(context);
    
    
    //// 畫出分針
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextRotateCTM(context, ([minuteAngle floatValue]) * M_PI / 180);
    CGContextScaleCTM(context, scale, scale);
    
    UIBezierPath* minuteHandPath = [UIBezierPath bezierPathWithRect: CGRectMake(-2.99, -64.92, 6, 55.92)];
    [hourAndMinuteHandColor setFill];
    [minuteHandPath fill];
    
    CGContextRestoreGState(context);
    
    

    
    
    //// 畫出中間的圓圈
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextScaleCTM(context, scale, scale);
    
    UIBezierPath* centreEmptyOvalPath = UIBezierPath.bezierPath;
    [centreEmptyOvalPath moveToPoint: CGPointMake(-4.42, -4.35)];
    [centreEmptyOvalPath addCurveToPoint: CGPointMake(-4.42, 4.33) controlPoint1: CGPointMake(-6.82, -1.95) controlPoint2: CGPointMake(-6.82, 1.93)];
    [centreEmptyOvalPath addCurveToPoint: CGPointMake(4.26, 4.33) controlPoint1: CGPointMake(-2.02, 6.73) controlPoint2: CGPointMake(1.86, 6.73)];
    [centreEmptyOvalPath addCurveToPoint: CGPointMake(4.26, -4.35) controlPoint1: CGPointMake(6.66, 1.93) controlPoint2: CGPointMake(6.66, -1.95)];
    [centreEmptyOvalPath addCurveToPoint: CGPointMake(-4.42, -4.35) controlPoint1: CGPointMake(1.86, -6.75) controlPoint2: CGPointMake(-2.02, -6.75)];
    [centreEmptyOvalPath closePath];
    [centreEmptyOvalPath moveToPoint: CGPointMake(7.78, -7.7)];
    [centreEmptyOvalPath addCurveToPoint: CGPointMake(7.78, 7.85) controlPoint1: CGPointMake(12.08, -3.41) controlPoint2: CGPointMake(12.08, 3.56)];
    [centreEmptyOvalPath addCurveToPoint: CGPointMake(-7.77, 7.85) controlPoint1: CGPointMake(3.49, 12.15) controlPoint2: CGPointMake(-3.48, 12.15)];
    [centreEmptyOvalPath addCurveToPoint: CGPointMake(-7.77, -7.7) controlPoint1: CGPointMake(-12.07, 3.56) controlPoint2: CGPointMake(-12.07, -3.41)];
    [centreEmptyOvalPath addCurveToPoint: CGPointMake(7.78, -7.7) controlPoint1: CGPointMake(-3.48, -12) controlPoint2: CGPointMake(3.49, -12)];
    [centreEmptyOvalPath closePath];
    [hourAndMinuteHandColor setFill];
    [centreEmptyOvalPath fill];
    
    CGContextRestoreGState(context);
    
    
    //// 畫出「12」
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextScaleCTM(context, scale, scale);
    
    CGRect text12Rect = CGRectMake(-10, -82, 21, 17);
    {
        NSString* textContent = @"12";
        NSMutableParagraphStyle* text12Style = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
        text12Style.alignment = NSTextAlignmentCenter;
        
        NSDictionary* text12FontAttributes = @{NSFontAttributeName: [UIFont fontWithName: @"Helvetica-Bold" size: 18], NSForegroundColorAttributeName: fontColor, NSParagraphStyleAttributeName: text12Style};
        
        [textContent drawInRect: CGRectOffset(text12Rect, 0, (CGRectGetHeight(text12Rect) - [textContent boundingRectWithSize: text12Rect.size options: NSStringDrawingUsesLineFragmentOrigin attributes: text12FontAttributes context: nil].size.height) / 2) withAttributes: text12FontAttributes];
    }
    
    CGContextRestoreGState(context);
    
    
    //// 畫出「3」
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextScaleCTM(context, scale, scale);
    
    CGRect text3Rect = CGRectMake(72, -9, 12, 17);
    {
        NSString* textContent = @"3";
        NSMutableParagraphStyle* text3Style = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
        text3Style.alignment = NSTextAlignmentCenter;
        
        NSDictionary* text3FontAttributes = @{NSFontAttributeName: [UIFont fontWithName: @"Helvetica-Bold" size: 18], NSForegroundColorAttributeName: fontColor, NSParagraphStyleAttributeName: text3Style};
        
        [textContent drawInRect: CGRectOffset(text3Rect, 0, (CGRectGetHeight(text3Rect) - [textContent boundingRectWithSize: text3Rect.size options: NSStringDrawingUsesLineFragmentOrigin attributes: text3FontAttributes context: nil].size.height) / 2) withAttributes: text3FontAttributes];
    }
    
    CGContextRestoreGState(context);
    
    
    //// 畫出「6」
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextScaleCTM(context, scale, scale);
    
    CGRect text6Rect = CGRectMake(-4, 65, 12, 17);
    {
        NSString* textContent = @"6";
        NSMutableParagraphStyle* text6Style = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
        text6Style.alignment = NSTextAlignmentCenter;
        
        NSDictionary* text6FontAttributes = @{NSFontAttributeName: [UIFont fontWithName: @"Helvetica-Bold" size: 18], NSForegroundColorAttributeName: fontColor, NSParagraphStyleAttributeName: text6Style};
        
        [textContent drawInRect: CGRectOffset(text6Rect, 0, (CGRectGetHeight(text6Rect) - [textContent boundingRectWithSize: text6Rect.size options: NSStringDrawingUsesLineFragmentOrigin attributes: text6FontAttributes context: nil].size.height) / 2) withAttributes: text6FontAttributes];
    }
    
    CGContextRestoreGState(context);
    
    
    //// 畫出「9」
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextScaleCTM(context, scale, scale);
    
    CGRect text9Rect = CGRectMake(-82, -8, 12, 17);
    {
        NSString* textContent = @"9";
        NSMutableParagraphStyle* text9Style = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
        text9Style.alignment = NSTextAlignmentCenter;
        
        NSDictionary* text9FontAttributes = @{NSFontAttributeName: [UIFont fontWithName: @"Helvetica-Bold" size: 18], NSForegroundColorAttributeName: fontColor, NSParagraphStyleAttributeName: text9Style};
        
        [textContent drawInRect: CGRectOffset(text9Rect, 0, (CGRectGetHeight(text9Rect) - [textContent boundingRectWithSize: text9Rect.size options: NSStringDrawingUsesLineFragmentOrigin attributes: text9FontAttributes context: nil].size.height) / 2) withAttributes: text9FontAttributes];
    }
    
    CGContextRestoreGState(context);
    
    
    //// 畫出錶盤刻度
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
    CGContextScaleCTM(context, scale, scale);
    
    UIBezierPath* markPath = UIBezierPath.bezierPath;
    [markPath moveToPoint: CGPointMake(-2, -85)];
    [markPath addLineToPoint: CGPointMake(2, -85)];
    [markPath addLineToPoint: CGPointMake(2, -93)];
    [markPath addLineToPoint: CGPointMake(-2, -93)];
    [markPath addLineToPoint: CGPointMake(-2, -85)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(-1, 93)];
    [markPath addLineToPoint: CGPointMake(3, 93)];
    [markPath addLineToPoint: CGPointMake(3, 85)];
    [markPath addLineToPoint: CGPointMake(-1, 85)];
    [markPath addLineToPoint: CGPointMake(-1, 93)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(-45, -72.15)];
    [markPath addLineToPoint: CGPointMake(-41.54, -74.15)];
    [markPath addLineToPoint: CGPointMake(-45.54, -81.08)];
    [markPath addLineToPoint: CGPointMake(-49, -79.08)];
    [markPath addLineToPoint: CGPointMake(-45, -72.15)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(44.87, 81.5)];
    [markPath addLineToPoint: CGPointMake(48.33, 79.5)];
    [markPath addLineToPoint: CGPointMake(44.33, 72.57)];
    [markPath addLineToPoint: CGPointMake(40.87, 74.57)];
    [markPath addLineToPoint: CGPointMake(44.87, 81.5)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(-75.07, -40)];
    [markPath addLineToPoint: CGPointMake(-73.07, -43.46)];
    [markPath addLineToPoint: CGPointMake(-80, -47.46)];
    [markPath addLineToPoint: CGPointMake(-82, -44)];
    [markPath addLineToPoint: CGPointMake(-75.07, -40)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(79.58, 48.13)];
    [markPath addLineToPoint: CGPointMake(81.58, 44.67)];
    [markPath addLineToPoint: CGPointMake(74.65, 40.67)];
    [markPath addLineToPoint: CGPointMake(72.65, 44.13)];
    [markPath addLineToPoint: CGPointMake(79.58, 48.13)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(-85, 2)];
    [markPath addLineToPoint: CGPointMake(-85, -2)];
    [markPath addLineToPoint: CGPointMake(-93, -2)];
    [markPath addLineToPoint: CGPointMake(-93, 2)];
    [markPath addLineToPoint: CGPointMake(-85, 2)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(93, 1)];
    [markPath addLineToPoint: CGPointMake(93, -3)];
    [markPath addLineToPoint: CGPointMake(85, -3)];
    [markPath addLineToPoint: CGPointMake(85, 1)];
    [markPath addLineToPoint: CGPointMake(93, 1)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(-72.57, 44)];
    [markPath addLineToPoint: CGPointMake(-74.57, 40.54)];
    [markPath addLineToPoint: CGPointMake(-81.5, 44.54)];
    [markPath addLineToPoint: CGPointMake(-79.5, 48)];
    [markPath addLineToPoint: CGPointMake(-72.57, 44)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(81.08, -45.87)];
    [markPath addLineToPoint: CGPointMake(79.08, -49.33)];
    [markPath addLineToPoint: CGPointMake(72.15, -45.33)];
    [markPath addLineToPoint: CGPointMake(74.15, -41.87)];
    [markPath addLineToPoint: CGPointMake(81.08, -45.87)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(-39.67, 75.07)];
    [markPath addLineToPoint: CGPointMake(-43.13, 73.07)];
    [markPath addLineToPoint: CGPointMake(-47.13, 80)];
    [markPath addLineToPoint: CGPointMake(-43.67, 82)];
    [markPath addLineToPoint: CGPointMake(-39.67, 75.07)];
    [markPath closePath];
    [markPath moveToPoint: CGPointMake(48.46, -79.58)];
    [markPath addLineToPoint: CGPointMake(45, -81.58)];
    [markPath addLineToPoint: CGPointMake(41, -74.65)];
    [markPath addLineToPoint: CGPointMake(44.46, -72.65)];
    [markPath addLineToPoint: CGPointMake(48.46, -79.58)];
    [markPath closePath];
    [markColor setFill];
    [markPath fill];
    
    CGContextRestoreGState(context);
}


@end

xcode6.1 SDK8.1測試沒問題!

代碼中已經有無比詳細的註釋,並且該控件簡單地使人髮指~ 我相信你看的懂得!

我想確定有同窗已經排着隊,準備好了板磚,雞蛋什麼的,「博主!你妹!說好的無比迅速敏捷地開發iOS超精美控件 哪裏迅速哪裏敏捷?說好的奇淫巧技呢?」

都說心急吃不了熱豆腐,我有說文章結束了麼?文章只是出軌而已了……

 

PaintCode

代碼是寫出來了, 可是在

-(void)drawRect:(CGRect)rect

 

方法中一筆一筆的勾畫出來,確實是累人~

因此我要祭出此次文章的純24K真大殺器——PaintCode

圖3

 

爲什麼要稱PaintCode爲終極大殺器?由於它真的很兇!若是說咱們剛剛的項目須要花2~3個小時才能完成 而有了PaintCode以後咱們只須要10~20分鐘!!!就問你怕不怕!!!

售價$99的PaintCode用起來就是爽!

我忽然想起本身的一個故事,有一年上大學,父親到車站來送我,臨上車前,父親叮囑我等他一下子他要過鐵道對面要給我買點東西,說我一我的過日子會很艱難,我看見他戴着黑布小帽,穿着黑布大馬褂,深青布棉袍,蹣跚地走到鐵道邊,慢慢探身下去,尚不大難。但是他穿過鐵道,要爬上那邊月臺,就不容易了。他用兩手攀着上面,兩腳再向上縮;他肥胖的身子向左微傾,顯出努力的樣子。這時我看見他的背影,個人淚很快地流下來了。我趕忙拭乾了淚。怕他看見,也怕別人看見。我再向外看時,他已抱了一個黑塑料袋子往回走了。過鐵道時,他先將塑料袋散放在地上,本身慢慢爬下,再抱起塑料袋走。到這邊時,我趕忙去攙他。他和我走到車上,將塑料袋一古腦兒放在個人皮大衣上:「最新的全是外國的動做片、遊戲、音樂光盤,好好照顧本身」,想起老父親微薄的退休金,我就有點氣憤:「爸,你怎麼……」,父親趕緊湊到個人耳邊:「D版的,八國聯軍當年搶得錢是該要回來的」,我:「……」

好了個人故事講完了 大家應該知道怎麼找PaintCode了額

我麼開始PaintCode之旅吧

打開Paint

圖4

 

就像PS同樣只要你畫的出,就能生成代碼(支持swift哦)

咱們就試試畫出DDClock來吧

選中Oval

圖5

按住shift鍵拖出一個規則的圓形 ,填充顏色,這個就是代碼中的rimPath

圖6

再次選中Oval,一樣的方法在拖一個圓出來,

圖7

這個就是代碼中的facePath。

在PaintCode中儘可能將全部的圖形、顏色都本身取一個名字,好比我把第一個Oval取名字rim,第二個Oval取名字face

這樣錶盤的邊框和中間都出來了額,接下來就是錶盤的刻度了

選中rect

圖8

拖出其中的一個小刻度 

圖9

而後選中這個小刻度複製出另外一個小刻度,放到第一個刻度的對面,就像這樣

圖10

而後按住shift鍵 同時選中這兩個小刻度,點擊工具欄的Union

圖11

這樣兩個小刻度就成爲了一個對象,這時點擊右側的Transforms,就會出現旋轉圖形的操做,把旋轉中心(圖12中綠色的瞄準星)拖到鐘錶的中心位置

圖12

 這樣設置Rotation的參數就能夠圍繞整個鐘錶旋轉這個刻度了,因此立刻同時複製這個刻度5份,分別操做旋轉,讓它們分別旋轉30、60、90、120、150這樣全部的刻度都出來了,而後再一次性的選中全部刻度Union一次,把全部刻度合併成一個圖形。

圖13

接下來就選中Text工具

圖14

選中恰當的字體和大小,畫出刻度值和上下午提示的AM/PM

圖15

最後是時針、分針和秒針了,作法是雷同的,聰明的你確定知道該怎麼作了,反正就是使用規則圖形,經過Union、Intersection、Difference的操做產生不規則的圖形

圖16

圖17

圖18

最後看個人項目大致狀況;

 

到了這一步其實就能夠直接複製代碼走人就OK拉

而後稍微謝謝項目的邏輯代碼,測試,OK啦,是否是把二、3個小時的事情10分鐘完成了?哈哈哈

其實PaintCode的強大遠不止於此,裏面的Variables的功能,能夠將圖形中的某個值設置成變量,好比代碼中的hourAngle、 minuteAngle 、 secondAngle 等,DDClock目前的大小的是固定的200x200,其實使用Variables添加scale的變量,還能夠動態的修改全部圖形的大小!固然還有Frame的使用啦……

後記

 

對於PaintCode博主也只是淺嘗而止,更多強大的功能,同窗們仍是本身挖掘吧。

這裏附上官網的地址,PaintCode 裏面有視頻教程,文檔等(視頻是油管網的,因此須要FQ,呵呵,你懂的)

這裏也附上我寫的項目源代碼 DDClock(尼瑪!github使用代理比直接訪問更快,你能忍?)

這個禮拜,完成了畢設的主題和一些細節,大概是設計一套移動客戶端和後臺服務器安全交互的方案,涉及到各類安全通訊,可靠性傳輸,內容加解密等內容,我會把這個設想寫到博客上的;

女友回老家了,剩下本身一我的擼啊擼T_T;

天殺的12306買了兩天都沒買到回家的票,明明買不到票,卻還要寫着有餘票,哎,最後我決定坐頭等艙回家了~

相關文章
相關標籤/搜索