https://github.com/YouXianMing

变换CALayer锚点实现模拟时钟的动画

变换CALayer锚点实现模拟时钟的动画

 

变换锚点得需要一点理论知识,看下图就能明白:).

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW15

开始实现模拟时钟效果:

//
//  RootViewController.m
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "YXGCD.h"

@interface RootViewController ()

@property (nonatomic, strong) GCDTimer *timer;

@end

// 将角度转换为弧度
#define DEGREES__TO__RADIANS(d)  ((d) * M_PI / 180.f)

@implementation RootViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 显示参考用的view
    UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 300, 300)];
    showView.layer.borderWidth = 1.f;
    showView.layer.cornerRadius = 150.f;
    showView.layer.borderColor = [UIColor redColor].CGColor;
    showView.center = self.view.center;
    [self.view addSubview:showView];
    
    // 新建layer
    CALayer *layer = [CALayer layer];
    layer.backgroundColor = [UIColor blackColor].CGColor;
    
    // 重置锚点
    layer.anchorPoint = CGPointMake(0.f, 0.f);
    
    // 设置layer的frame值(在showView正中间摆放)
    layer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 150);
    
    // 添加进showView中
    [showView.layer addSublayer:layer];
    
    // 定时器
    _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
    [_timer event:^{
        static int i = 1;
        
        // 每秒增加的角度
        layer.transform = \
            CATransform3DMakeRotation(DEGREES__TO__RADIANS((360/60.f) * i++), 0.0, 0.0, 1.0);
    } timeInterval:NSEC_PER_SEC];
    [_timer start];
}


@end

 

重要的代码:

以下是最终效果:

完整代码:

//
//  RootViewController.m
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "YXGCD.h"

static NSDateFormatter* _DMLogDateFormatter = nil;

@interface RootViewController ()

@property (nonatomic, strong) GCDTimer *timer;
@property (nonatomic, strong) UILabel  *timeLabel;

@end

// 将角度转换为弧度
#define DEGREES__TO__RADIANS(d)  ((d) * M_PI / 180.f)

@implementation RootViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blackColor];
    
    // 日期格式
    _DMLogDateFormatter = [[NSDateFormatter alloc] init];
    [_DMLogDateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
    [_DMLogDateFormatter setDateFormat:@"HH:mm:ss"];
    
    // 显示label
    _timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 30)];
    _timeLabel.textAlignment = NSTextAlignmentCenter;
    _timeLabel.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:29.f];
    _timeLabel.textColor = [UIColor cyanColor];
    _timeLabel.center = self.view.center;
    _timeLabel.y += 190;
    [self.view addSubview:_timeLabel];
    
    // 显示参考用的view
    UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 300, 300)];
    showView.layer.borderWidth = 1.f;
    showView.layer.cornerRadius = 150.f;
    showView.layer.borderColor = [UIColor redColor].CGColor;
    showView.center = self.view.center;
    [self.view addSubview:showView];
    
    // 新建秒钟Layer
    // ----------------------------------------------------- //
    CALayer *secondLayer = [CALayer layer];
    secondLayer.backgroundColor = [UIColor whiteColor].CGColor;
    
    // 重置锚点
    secondLayer.anchorPoint = CGPointMake(0.f, 0.f);
    
    // 设置layer的frame值(在showView正中间摆放)
    secondLayer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 140);
    
    // 添加进showView中
    [showView.layer addSublayer:secondLayer];
    
    
    // 新建分钟Layer
    // ----------------------------------------------------- //
    CALayer *minuteLayer = [CALayer layer];
    minuteLayer.backgroundColor = [UIColor greenColor].CGColor;
    
    // 重置锚点
    minuteLayer.anchorPoint = CGPointMake(0.f, 0.f);
    
    // 设置layer的frame值(在showView正中间摆放)
    minuteLayer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 120);
    
    // 添加进showView中
    [showView.layer addSublayer:minuteLayer];
    
    
    // 新建时钟Layer
    // ----------------------------------------------------- //
    CALayer *hourLayer = [CALayer layer];
    hourLayer.backgroundColor = [UIColor blueColor].CGColor;
    
    // 重置锚点
    hourLayer.anchorPoint = CGPointMake(0.f, 0.f);
    
    // 设置layer的frame值(在showView正中间摆放)
    hourLayer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 100);
    
    // 添加进showView中
    [showView.layer addSublayer:hourLayer];
    
    
    // 定时器
    _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
    [_timer event:^{
        
        NSString *timerNow = [_DMLogDateFormatter stringFromDate:[NSDate date]];
        NSArray *timeArray = [timerNow componentsSeparatedByString:@":"];

        // 获取到时间
        float sec =  [timeArray[2] intValue];
        float min =  [timeArray[1] intValue] + sec / 60.f;
        float hour = [timeArray[0] intValue] + min / 60.f;
        
        secondLayer.transform = \
            CATransform3DMakeRotation(DEGREES__TO__RADIANS(360/60.f)*sec + \
                                      DEGREES__TO__RADIANS(180), \
                                      0.0, 0.0, 1.0);
        
        minuteLayer.transform = \
        CATransform3DMakeRotation(DEGREES__TO__RADIANS(360/60.f)*min + \
                                  DEGREES__TO__RADIANS(180), \
                                  0.0, 0.0, 1.0);
        
        hourLayer.transform = \
        CATransform3DMakeRotation(DEGREES__TO__RADIANS(360/24.f)*hour + \
                                  DEGREES__TO__RADIANS(360), \
                                  0.0, 0.0, 1.0);
        
        _timeLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d",
                           [timeArray[0] intValue],
                           [timeArray[1] intValue],
                           [timeArray[2] intValue]];
        
    } timeInterval:NSEC_PER_SEC];
    [_timer start];
}


@end
RootViewController.m

 

 

 

posted @ 2014-06-03 11:07  YouXianMing  阅读(835)  评论(1编辑  收藏  举报