物体角度基于当前时间

时间:2011-01-30 15:03:57

标签: iphone uiview calayer rotation clock

请仔细聆听,因为这是具体的。我正在尝试在iPhone SDK中制作模拟时钟。我已经尝试了三个星期了,我已经问了五个关于SO的问题,我仍然发现几乎没什么。我需要帮助。我想要一个根据当前时间旋转的钟针。我现在主要专注于秒针,因为它看起来最简单。

我不一定关心用于旋转时钟指针(CALayers,UIView等)的东西,只要它做它需要做的事情。非常感谢任何形式的帮助。谢谢。

编辑:我还需要双手成像。希望这不是太多。 :(

2 个答案:

答案 0 :(得分:3)

你问了same question的种类,我说Layers好多了......好吧这次我写的洞程序创纪录的时间不到三周;)。 如果您想使用图像,请获取图像并将其设置在initWithFrame:

接口:ClockView.h

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface ClockView : UIView {
    CALayer *containerLayer;
    CALayer *hourHand;
    CALayer *minHand;
    CALayer *secHand;
    NSTimer *timer;
}
- (void) start;
- (void) stop;
@end

实施:ClockView.m

#import "ClockView.h"

@implementation ClockView

float Degrees2Radians(float degrees) { return degrees * M_PI / 180; }

- (void) start{
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self 
                                                    selector:@selector(updateClock) 
                                                    userInfo:nil repeats:YES];
}
- (void) stop{
    [timer invalidate];
    timer = nil;
}

- (void) updateClock{
    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) 
                                                                       fromDate:[NSDate date]];
    NSInteger seconds = [dateComponents second];
    NSInteger minutes = [dateComponents minute];
    NSInteger hours = [dateComponents hour];
    //correction of inverted clock
    seconds += 30; seconds %=60;
    minutes += 30; minutes %=60;
    hours += 6; hours %=12;

    hourHand.transform = CATransform3DMakeRotation (Degrees2Radians(hours*360/12), 0, 0, 1);
    minHand.transform = CATransform3DMakeRotation (Degrees2Radians(minutes*360/60), 0, 0, 1);
    secHand.transform = CATransform3DMakeRotation (Degrees2Radians(seconds*360/60), 0, 0, 1);
}
- (void) layoutSubviews{
    [super layoutSubviews];

    containerLayer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);

    float length = MIN(self.frame.size.width, self.frame.size.height)/2;
    CGPoint c = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
    hourHand.position = minHand.position = secHand.position = c;

    hourHand.bounds = CGRectMake(0,0,10,length*0.5);
    minHand.bounds = CGRectMake(0,0,8,length*0.8);
    secHand.bounds = CGRectMake(0,0,4,length);

    hourHand.anchorPoint = CGPointMake(0.5,0.0);
    minHand.anchorPoint = CGPointMake(0.5,0.0);
    secHand.anchorPoint = CGPointMake(0.5,0.0);

}

- (id)initWithFrame:(CGRect)frame {

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

        containerLayer = [[CALayer layer] retain];

        hourHand = [[CALayer layer] retain];
        minHand = [[CALayer layer] retain];
        secHand = [[CALayer layer] retain];

        //paint your hands: simple colors
        hourHand.backgroundColor = [UIColor blackColor].CGColor;
        hourHand.cornerRadius = 3;
        minHand.backgroundColor = [UIColor grayColor].CGColor;
        secHand.backgroundColor = [UIColor whiteColor].CGColor;
        secHand.borderWidth = 1.0;
        secHand.borderColor = [UIColor grayColor].CGColor;

        //put images
        //hourHand.contents = (id)[UIImage imageNamed:@"hour.png"].CGImage;
        //minHand.contents = (id)[UIImage imageNamed:@"min.png"].CGImage;
        //secHand.contents = (id)[UIImage imageNamed:@"sec.png"].CGImage;

        [containerLayer addSublayer:hourHand];
        [containerLayer addSublayer:minHand];
        [containerLayer addSublayer:secHand];
        [self.layer addSublayer:containerLayer];

        self.layer.borderColor = [UIColor greenColor].CGColor;
        self.layer.borderWidth = 1.0;

    }
    return self;
}
- (void)dealloc {
    [self stop];
    [hourHand release];
    [minHand release];
    [secHand release];
    [containerLayer release];
    [super dealloc];
}
@end

用法:

#import "ClockView.h"

- (void)viewDidLoad {
    [super viewDidLoad];

    ClockView *clockView = [[ClockView alloc] initWithFrame:CGRectMake(0,0,100,100)];
    [self.view addSubview:clockView];
    [clockView start];
    [clockView release];

}

答案 1 :(得分:1)

三个星期?严重<?是/> 我的时钟非常难看,但它是一个时钟,看起来很好,可以猜出它的当前时间。

static inline float PGVmyRadians(double degrees) { return degrees * M_PI / 180; }

- (void)drawRect:(CGRect)rect {
    CGFloat boundsWidth = self.bounds.size.width;
    CGFloat boundsHeight = self.bounds.size.height;
    CGPoint center = CGPointMake(boundsWidth/2, boundsHeight/2);

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, self.bounds);
    CGContextSetFillColorWithColor(context, [UIColor magentaColor].CGColor);
    CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextSetLineWidth(context, 10);
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextAddArc(context, boundsWidth/2, boundsHeight/2, boundsWidth/2, PGVmyRadians(0), PGVmyRadians(360), 0);

    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:[NSDate date]];
    NSInteger seconds = [dateComponents second];
    NSInteger minutes = [dateComponents minute];
    NSInteger hour = [dateComponents hour];

    if (hour > 12) {
        hour -= 12;
    }

    CGFloat angleSec = ((seconds - 15) / 60.0) * 360.0;
    CGFloat thetaSec = PGVmyRadians(angleSec);
    CGFloat lengthSec = 0.9 * boundsHeight/2;
    CGFloat Xsec = center.x + lengthSec * cos(thetaSec);
    CGFloat Ysec = center.y + lengthSec * sin(thetaSec);

    CGContextMoveToPoint(context, center.x, center.y);
    CGContextAddLineToPoint(context, Xsec, Ysec);

    CGFloat angleMin = ((minutes - 15) / 60.0) * 360.0;
    CGFloat thetaMin = PGVmyRadians(angleMin);
    CGFloat lengthMin = 0.7 * boundsHeight/2;
    CGFloat Xmin = center.x + lengthMin * cos(thetaMin);
    CGFloat Ymin = center.y + lengthMin * sin(thetaMin);

    CGContextMoveToPoint(context, center.x, center.y);
    CGContextAddLineToPoint(context, Xmin, Ymin);

    CGFloat angleHour = ((hour - 3) / 12.0) * 360.0;
    CGFloat thetaHour = PGVmyRadians(angleHour);
    CGFloat lengthHour = 0.5 * boundsHeight/2;
    CGFloat Xhour = center.x + lengthHour * cos(thetaHour);
    CGFloat Yhour = center.y + lengthHour * sin(thetaHour);

    CGContextMoveToPoint(context, center.x, center.y);
    CGContextAddLineToPoint(context, Xhour, Yhour);
    CGContextStrokePath(context);
}