变换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
时间: 2024-12-28 21:16:33

变换CALayer锚点实现模拟时钟的动画的相关文章

javascript实现模拟时钟的方法

  本文实例讲述了javascript实现模拟时钟的方法.分享给大家供大家参考.具体实现方法如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta h

layout-把 android 的模拟时钟在最左边对齐

问题描述 把 android 的模拟时钟在最左边对齐 程序中有一个 xml 文件,要在左边显示一个模拟时钟,在它的右边显示日期和时间.现在我不能把时钟在左边对齐,如何实现? <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:orientation="vertical" android:id="@+id/base_layout" andro

如何使用JFrame完成动态模拟时钟_java

这篇文章介绍了使用JFrame完成动态模拟时钟,在面板中绘制时钟并提取系统当前时刻,主方法中暂停线程1秒,刷新面板. 实现代码如下 import javax.swing.*; import java.awt.*; import java.util.*; import java.lang.Thread; import java.text.DecimalFormat; public class StillClock extends JPanel { /** * @param args */ priv

指针- vc6.0模拟时钟问题,两个循环无法同时运行

问题描述 vc6.0模拟时钟问题,两个循环无法同时运行 #include ""graphics.h""#include ""conio.h""#include ""time.h""#include ""math.h""int main(){int x0=400y0=200;int x1=0y1=0;int h=0;int m=0;int r=90;

android 时钟 卡顿-android模拟时钟 秒针卡顿(有时候秒针会不走,然后下一秒会跳动三个格子)

问题描述 android模拟时钟 秒针卡顿(有时候秒针会不走,然后下一秒会跳动三个格子) package custom.analog.clock; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.BroadcastReceiver; import android.content.res.Resourc

android 模拟时钟 手指触动旋转指针

问题描述 我想在android上实现一个模拟时钟,比如说只有一个时针(秒针,分针不要),怎么样可以用手指去触动那个指针,然后跟着手指旋转移动,有什么事件吗?谁能给点思路啊 问题补充:可是如何获取触电坐标啊,俺是新手,不会呢,忘指教,谢谢 解决方案 圆心位置你是知道的吧, 那么在 OnTouchListener 事件中,的MotionEvent.ACTION_DOWN: 来检测是否处于指针的位置,是的话,设个标志,当手指移动时,MotionEvent.ACTION_MOVE: 事件中来重画指针im

jquery 时间选择器 ClockPicker(模拟时钟)用法

最近项目中需要用到一个时间选择器,之前用到的 bootstrap-datetimepicker 在选择日期时蛮好用,但是它的时间选择(时:分)却有点别扭,后来发现 Android 上调闹铃时的选择器挺不错,于是决定自己开发一个类似的模拟时钟的时间选择器. 最开始只是打算做一个用于 Bootstrap 的组件,后来发现我只是用了 Bootstrap 的 .popover 和一些 .btn 的样式,于是我将这些样式取出来,让它同时支持单独作为一个 jQuery 插件. 先看看截图,使用过 Andro

javascript实现模拟时钟的方法_javascript技巧

本文实例讲述了javascript实现模拟时钟的方法.分享给大家供大家参考.具体实现方法如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>javascript模拟时钟</title&

Clockywock 0.2.3H发布 Linux模拟时钟

Clockywock 是一个Linux控制台的ncurses模拟时钟. Clockywock 0.2.3H该版本修正了额外的编译警告问题. 软件信息:http://soomka.com/ 下载地址:http://soomka.com/clockywock-0.2.3H.tar.gz