以小 Demo 形式繼續學習動畫,同時再次發現我們中國文化的強大啊,國外有好多詞根本沒有,像太極通常的翻譯的就是
Tai Ji
,哈哈
截斷的旋轉太極圖
#import "TaiJiView.h"
@implementation TaiJiView {
NSTimer *_timer;
CGFloat _currentRotate; // 當前旋轉偏移
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_currentRotate = 0.0;
self.backgroundColor = [UIColor clearColor];
_timer = [NSTimer scheduledTimerWithTimeInterval:0.05f target:self selector:@selector(updateRotate) userInfo:nil repeats:YES];
}
return self;
}
- (void)dealloc {
[_timer invalidate];
_timer = nil;
}
- (void)updateRotate {
_currentRotate += 0.01;
// setNeedsDisplay會調用自動調用drawRect方法
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
// 獲取中心點
CGFloat x = self.frame.size.width/2;
CGFloat y = self.frame.size.height/2;
// 獲取真正的半徑
CGFloat radius = MIN(x, y);
// 設置當前的偏移量
CGFloat runAngle = M_PI*_currentRotate;
if (runAngle >= 2*M_PI) {
runAngle -= 2*M_PI;
}
// 開始畫
CGContextRef context = UIGraphicsGetCurrentContext();
// 經典的黑白顏色
CGColorRef whiteColor =[[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:1.0f] CGColor];
CGColorRef blackColor =[[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f] CGColor];
/*
CGContextAddArc(CGContextRef __nullable c, CGFloat x, CGFloat y,
CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)
注意: startAngle: 開始角度
endAngle :結束角度
clockwise: 0 為順時針,1 逆時針
**/
// 獲取下部分白色的半圓(假設第一次時)
CGContextSetFillColor(context, CGColorGetComponents(whiteColor));
CGContextAddArc(context, x, y, radius, 0+runAngle, M_PI+runAngle, 0);
CGContextClosePath(context);
CGContextFillPath(context);
// 獲取上部分黑色的半圓
CGContextSetFillColor(context, CGColorGetComponents( blackColor));
CGContextAddArc(context, x, y, radius, M_PI+runAngle, M_PI*2+runAngle, 0);
CGContextClosePath(context);
CGContextFillPath(context);
//再畫右邊上部分白色的半圓
CGContextSetFillColor(context, CGColorGetComponents( whiteColor));
CGContextAddArc(context, x+radius/2*cos(runAngle), y+radius/2*sin(runAngle), radius/2, M_PI+runAngle, M_PI*2+runAngle, 0);
CGContextClosePath(context);
CGContextFillPath(context);
// 再畫左邊下部分黑色的半圓
CGContextSetFillColor(context, CGColorGetComponents(blackColor));
CGContextAddArc(context, x-radius/2*cos(runAngle), y-radius/2*sin(runAngle), radius/2, 0+runAngle, M_PI+runAngle, 0);
CGContextClosePath(context);
CGContextFillPath(context);
// 再畫兩條半徑,相當于分割線
CGContextSetStrokeColorWithColor(context, whiteColor);
CGContextMoveToPoint(context, x+radius*cos(runAngle), y+radius*sin(runAngle));
CGContextAddLineToPoint(context, x, y);
CGContextStrokePath(context);
CGContextSetStrokeColorWithColor(context, blackColor);
CGContextMoveToPoint(context, x-radius*cos(runAngle), y-radius*sin(runAngle));
CGContextAddLineToPoint(context, x, y);
CGContextStrokePath(context);
// 再下面就是兩個小圓啦
CGContextSetFillColor(context, CGColorGetComponents( whiteColor));
CGContextAddArc(context, x-radius/2*cos(runAngle), y-radius/2*sin(runAngle), radius/4, 0, M_PI*2, 0);
CGContextClosePath(context);
CGContextFillPath(context);
CGContextSetFillColor(context, CGColorGetComponents( blackColor));
CGContextAddArc(context, x+radius/2*cos(runAngle), y+radius/2*sin(runAngle), radius/4, 0, M_PI*2, 0);
CGContextClosePath(context);
CGContextFillPath(context);
}
@end
注意一:標顏色時,上面一種獲取顏色在此處是無效的
CGColorRef blackColor = [UIColor blackColor].CGColor;
CGColorRef blackColor =[[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f] CGColor];
通過下面這些注釋,我們可以理解類似[UIColor blackColor]獲取顏色值,實際上相當是相當獲取緩存下來的。
// Some convenience methods to create colors.
// These colors will be as calibrated as possible.
// These colors are cached.
而上述第一種情況的時候,可能并沒能拿到緩存的顏色值,或者說此處是初始化CGColorRef ,并不是簡單的獲取顏色值 ,所以無效。
注意二: setNeedsDisplay
異步執行的方法
一旦調用setNeedsDisplay就會調用自動調用drawRect方法
而setNeedsLayout會默認調 用layoutSubViews,就可以處理子視圖中的一些數據。
可以說,setNeedsDisplay方便繪圖,而layoutSubViews方便更新數據。
注意三: CGContextAddArc 方法
CGContextAddArc(CGContextRef __nullable c, CGFloat x, CGFloat y,
CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)
注意: startAngle: 開始角度
endAngle :結束角度
clockwise: 0 為順時針,1 為逆時針
PS:場景來自【iOS開發范例實戰寶典.進階篇】。