基于当前时间的物体角度

发布于 2024-10-14 21:16:17 字数 263 浏览 2 评论 0原文

仔细听,因为这是具体的。我正在尝试在 iPhone SDK 中制作一个模拟时钟。我已经尝试完成这个任务三个星期了,我已经问了五个问题,但我仍然几乎什么也没找到。我需要帮助。我想要一个只根据当前时间旋转的时钟指针。我现在主要关注二手,因为它看起来是最简单的。

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

编辑:我还需要手作为图像。希望这还不算太多。 :(

Listen carefully, because this is specific. I'm trying to make an analog clock in iPhone SDK. I've been trying to accomplish this for three weeks now, I've asked five questions on SO, and I still have found almost NOTHING. I need help. I want to have a clock hand that simply rotates depending on the current time. I'm mostly focused on the second hand right now because it seems like the easiest.

I don't necessarily care what is used to rotate the clock hand (CALayers, UIView, etc.), just as long as it does what it needs to do. Any sort of help is greatly, greatly appreciated. Thanks.

EDIT: I also need the hands to be images. Hopefully that isn't too much. :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

五里雾 2024-10-21 21:16:17

您问了同样的问题,我说图层要好得多。 .. 这次我在不到三周的时间内编写了这个洞程序;)。
如果你想使用图像,那么获取你的图像并将它们设置在 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];

}

You asked kind of the same question and I said that Layers is much better... well this time I have written the hole program in a record time than less than three weeks ;).
If you want to use images then get your images and set them inside initWithFrame:

Interface: 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

Implementation: 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

Usage:

#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];

}
最初的梦 2024-10-21 21:16:17

三个星期?认真的吗?
我的时钟很丑陋,但它是一个时钟,而且看起来足够好,可以从中猜测当前时间。

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);
}

three weeks? Seriously?
my clock is very fugly but it is a clock, and it looks good enough to guess the current time from it.

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文