0

私は時計プロジェクトに取り組んでいます.12時間時計の針(時、分、秒)の回転を実装する方法を知っています。私が使用したコードは次のとおりです

CGFloat secAngle,minAngle,hourAngle;

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



if (timeFormat == 12)//12 hour clock
{

    if (hours > 12) hours -=12; //PM

     secAngle = Degrees2Radians(seconds/60.0*360);
     minAngle = Degrees2Radians(minutes/60.0*360);

     hourAngle = Degrees2Radians(hours/12.0*360) + minAngle/12.0;

    //secHand.transform = CATransform3DMakeRotation (secAngle+M_PI, 0, 0, 1);
    minHand.transform = CATransform3DMakeRotation (minAngle+M_PI, 0, 0, 1);
    hourHand.transform = CATransform3DMakeRotation (hourAngle+M_PI, 0, 0, 1);
}
else //24 hour clock
{

    secAngle = Degrees2Radians(seconds/60.0*360);
    minAngle = Degrees2Radians(minutes/60.0*360);
    hourAngle = (30 * hours + minutes / 2) /2;

    //secHand.transform = CATransform3DMakeRotation(secAngle * M_PI / 180,0,0,1);
    minHand.transform = CATransform3DMakeRotation(minAngle * M_PI ,0,0,1);
    hourHand.transform = CATransform3DMakeRotation(hourAngle * M_PI,0,0,1);


}

しかし、24時間時計を実装しようとすると。機能していません。このプロジェクトを実行するたびに、時計が間違ったタイミングを示します。

誰が私が何をしたのか教えてもらえますか。よろしくお願いします

4

2 に答える 2

4

方法は次のとおりです。顔の中心と角度を使用して、手の端点のx、y位置を計算します。そこから、描画は簡単です。これが完全な文字盤クラスです。これはUIViewのサブクラスです。毎秒時間プロパティを設定し、それは魅力のように機能します...

//
//  ClockFace.h
//

#import <UIKit/UIKit.h>

@interface ClockFace : UIView

@property (strong,nonatomic) NSDate *time;

@end


//  ClockFace.m

#import "ClockFace.h"

@interface ClockFace ()

@property(assign,nonatomic) CGPoint boundsCenter;
@property(assign,nonatomic) NSInteger seconds;
@property(assign,nonatomic) NSInteger minutes;
@property(assign,nonatomic) NSInteger hours;

@end

@implementation ClockFace

@synthesize time=_time;
@synthesize boundsCenter=_boundsCenter;

- (id)initWithCoder:(NSCoder *)aDecoder {

    self = [super initWithCoder:aDecoder];
    if (self) {
        _boundsCenter = CGPointMake(self.bounds.size.width/2.0, self.bounds.size.height/2.0);
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        _boundsCenter = CGPointMake(self.bounds.size.width/2.0, self.bounds.size.height/2.0);
    }
    return self;
}

- (CGPoint)secondsHandPosition {

    float secondsAsRadians = (float)self.seconds / 60.0 * 2.0 * M_PI - M_PI_2;
    float handRadius = self.frame.size.width / 2.4;
    return CGPointMake(handRadius*cosf(secondsAsRadians)+self.boundsCenter.x, handRadius*sinf(secondsAsRadians)+self.boundsCenter.y);
}

- (CGPoint)minutesHandPosition {

    float minutesAsRadians = (float)self.minutes / 60.0 * 2.0 * M_PI - M_PI_2;
    float handRadius = self.frame.size.width / 2.2;
    return CGPointMake(handRadius*cosf(minutesAsRadians)+self.boundsCenter.x, handRadius*sinf(minutesAsRadians)+self.boundsCenter.y);
}

- (CGPoint)hoursHandPosition {

    float hoursAsRadians = (float)self.hours / 12.0 * 2.0 * M_PI - M_PI_2;
    float handRadius = self.frame.size.width / 3.8;
    return CGPointMake(handRadius*cosf(hoursAsRadians)+self.boundsCenter.x, handRadius*sinf(hoursAsRadians)+self.boundsCenter.y);
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGFloat zClear[4] = {1.0,1.0,1.0,0.0};
    CGContextSetFillColor(context, zClear); 
    CGContextFillRect(context, rect);

    CGRect face = CGRectInset(rect, 1.0, 1.0);
    CGContextSetLineWidth(context, 1.0);
    CGContextAddEllipseInRect(context, face);
    CGContextStrokePath(context);

    CGRect center = CGRectMake(self.boundsCenter.x-2.0, self.boundsCenter.y-2.0, 4.0, 4.0);
    CGContextAddEllipseInRect(context, center);
    CGContextStrokePath(context);

    CGFloat red[4] = {1.0f, 0.0f, 0.0f, 1.0f};
    CGPoint secondsHandPosition = [self secondsHandPosition];

    CGContextSetStrokeColor(context, red);
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, self.boundsCenter.x, self.boundsCenter.y);
    CGContextAddLineToPoint(context, secondsHandPosition.x, secondsHandPosition.y);
    CGContextStrokePath(context);

    CGFloat black[4] = {0.0f, 0.0f, 0.0f, 1.0f};
    CGPoint minutesHandPosition = [self minutesHandPosition];

    CGContextSetStrokeColor(context, black);
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, self.boundsCenter.x, self.boundsCenter.y);
    CGContextAddLineToPoint(context, minutesHandPosition.x, minutesHandPosition.y);
    CGContextStrokePath(context);

    CGPoint hoursHandPosition = [self hoursHandPosition];

    CGContextSetStrokeColor(context, black);
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, self.boundsCenter.x, self.boundsCenter.y);
    CGContextAddLineToPoint(context, hoursHandPosition.x, hoursHandPosition.y);
    CGContextStrokePath(context);
}

- (void)setTime:(NSDate *)time {

    _time = time;

    static NSCalendar *gregorian;

    if (!gregorian) gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *weekdayComponents =
    [gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:time];

    self.hours = [weekdayComponents hour];
    if (self.hours > 12) self.hours -= 12;
    self.minutes = [weekdayComponents minute];
    self.seconds = [weekdayComponents second];

    [self setNeedsDisplay];
}


@end

これをViewControllerで使用するには、プロパティを作成します。

#import "ClockFace.h"

// ...

@property(strong, non atomic) ClockFace *clockFace;

ビューで読み込まれました(またはカスタムビューを追加する方法を知っている場合はストーリーボードで):

self.clockFace = [[ClockFace alloc] initWithFrame:CGRectMake(10, 10, 300, 300)];

時計を動かしたいときはいつでも、タイマーを設定してください。

[NSTimer scheduledTimerWithTimeInterval:1.0
    target:self
    selector:@selector(timerFired:)
    userInfo:nil
    repeats:NO];

タイマーが作動したら、時計に何時かを伝えます。

- (void)timerFired:(NSTimer *)timer {

    self.clockFace.time = [NSDate date];
}
于 2013-02-12T18:39:37.550 に答える