0
我試圖在UIView中實現時鐘臉 - 沒有太多的運氣。問題是鐘錶上的手完全處於錯誤的位置(即指向錯誤的時間)。我很確定我的代碼的邏輯是正確的 - 但顯然存在明顯的錯誤。在UIView中實現時鐘臉
我的測試應用程序是一個iOS單一視圖應用程序。 ViewController.h看起來是這樣的:
#import <UIKit/UIKit.h>
@interface Clock : UIView {
UIColor* strokeColour;
UIColor* fillColour;
float strokeWidth;
NSDate* clockTime;
CGPoint clockCentre;
float clockRadius;
}
- (id)initWithCentre:(CGPoint)centre
radius:(float)radius
borderWidth:(float)width
facecolour:(UIColor*)fill
handcolour:(UIColor*)handFill
time:(NSDate*)time;
@end
@interface ViewController : UIViewController
@end
和ViewController.m看起來是這樣的:
#import "ViewController.h"
@implementation Clock
- (id)initWithCentre:(CGPoint)centre
radius:(float)radius
borderWidth:(float)width
facecolour:(UIColor*)fill
handcolour:(UIColor*)handFill
time:(NSDate*)time {
CGRect frame = CGRectMake(centre.x-radius,
centre.y-radius,
radius*2,
radius*2);
if (self = [super initWithFrame:frame]) {
// Initialization code
strokeColour = fill;
fillColour = handFill;
strokeWidth = width;
clockRadius = radius;
clockTime = time;
clockCentre.x = frame.size.width/2;
clockCentre.y = frame.size.height/2;
}
return self;
}
- (void)drawRect:(CGRect)rect {
double red, green, blue, alpha;
CGRect circleRect;
circleRect.origin.x = rect.origin.x+strokeWidth;
circleRect.origin.y = rect.origin.y+strokeWidth;
circleRect.size.width = rect.size.width - (strokeWidth*2);
circleRect.size.height = rect.size.height - (strokeWidth*2);
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(contextRef, strokeWidth);
[fillColour getRed:&red green:&green blue:&blue alpha:&alpha];
CGContextSetRGBFillColor(contextRef, red, green, blue, alpha);
[strokeColour getRed:&red green:&green blue:&blue alpha:&alpha];
CGContextSetRGBStrokeColor(contextRef, red, green, blue, alpha);
CGContextFillEllipseInRect(contextRef, circleRect);
CGContextStrokeEllipseInRect(contextRef, circleRect);
CGContextSetLineWidth(contextRef, strokeWidth);
[strokeColour getRed:&red green:&green blue:&blue alpha:&alpha];
CGContextSetRGBStrokeColor(contextRef, red, green, blue, alpha);
float hourAngle, minuteAngle, secondAngle, angle;
double endX, endY;
NSCalendar *cal = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSUInteger units = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *components = [cal components:units fromDate:clockTime];
hourAngle = (components.hour /12.0) * M_PI * 2.0;
minuteAngle = (components.minute/60.0) * M_PI * 2.0;
secondAngle = (components.second/60.0) * M_PI * 2.0;
//minute hand
angle = minuteAngle;
endX = cos(angle) * (clockRadius*0.85) + clockCentre.x;
endY = sin(angle) * (clockRadius*0.85) + clockCentre.y;
CGContextMoveToPoint(contextRef,clockCentre.x,clockCentre.y);
CGContextAddLineToPoint(contextRef,endX,endY);
CGContextStrokePath(contextRef);
//hour hand
angle = hourAngle;
endX = cos(angle) * (clockRadius*0.65) + clockCentre.x;
endY = sin(angle) * (clockRadius*0.65) + clockCentre.y;
CGContextSetLineWidth(contextRef, strokeWidth*1.5);
CGContextMoveToPoint(contextRef,clockCentre.x,clockCentre.y);
CGContextAddLineToPoint(contextRef,endX,endY);
CGContextStrokePath(contextRef);
}
@end
@interface ViewController()
@end
@implementation ViewController
- (UIView*)drawClockFaceWithCentre:(CGPoint)centre
radius:(float)radius
time:(NSDate*)time
colour:(UIColor*)colour
backgroundColour:(UIColor*)bgcolour {
UIView* clock = [[Clock alloc]initWithCentre:centre
radius:radius
borderWidth:6.0
facecolour:bgcolour
handcolour:colour
time:time];
clock.backgroundColor = [UIColor clearColor];
return clock;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CGPoint centre;
centre.x=200;
centre.y=200;
[self.view addSubview:[self drawClockFaceWithCentre:centre
radius:100
time:[NSDate date]
colour:[UIColor blackColor]
backgroundColour:[UIColor whiteColor]]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
我敢肯定,這是很簡單的東西,我做錯了 - 在我的數學是錯誤的。任何人都可以看到這個錯誤(並且任何其他可以進行改進的建議都會受到歡迎,但要記住(當然),這只是一個簡單的測試工具)。
考慮使用CAShapeLayer作爲鍾針(每個針對一個)並將它們存儲爲變量。然後只是變換旋轉他們 – Kegluneq 2015-04-01 09:05:23
這不會解決問題,但它?因爲我仍然需要旋轉它們 - 這是我的旋轉問題。角度錯了。 – headbanger 2015-04-01 10:17:34
不,但它會使代碼更具可讀性,更易於維護和更輕鬆地進行計算(而不是三角函數,在這種情況下,只需要獲得正確的2pi百分比即可輕鬆搞定錯誤)。 – Kegluneq 2015-04-01 10:42:15