XZ_iOS之核心动画高级技巧之锚点、时钟效果和LCD风格的数字方式显示的实现

锚点

    anchorPoint 是用来移动图层的把柄。视图中的center属性和图层中的position属性都指定了anchorPoint相对于父图层的位置。图层的anchorPoint通过position来控制它的frame的位置。默认来说,anchorPoint位于图层的中点,所以图层将会以这个点为中心放置。

    图层的anchorPoint可以被移动,比如你可以把它置于图层的frame的左上角,于是图层的内容将会向右下角的position方向移动,而不是居中了。如下图:


    注意:当改变anchorPoint,position属性保持固定的值并没有发生变化,但是frame却移动了。

    anchorPoint用单位坐标来描述,也就是图层的相对坐标,图层左上角是{0,0},右下角是{1,1},因此默认坐标是{0.5,0.5}。anchorPoint可以通过指定x和y值小于0或者大于1,使它放置在图层范围之外。

时钟效果图,我是自己截的图片,有点丑,效果是实现了,哈哈,如下图:


实现的原理:

    获取到当前时间,根据当前时间,以及时钟的运转规律:

    1、秒针每一秒都动一下,旋转的角度是当前时间的秒数/60*360;

    2、秒针旋转60次,分钟旋转一次,旋转的角度是当前时间的分钟数/60*360;

    3、分针旋转60次,时针旋转一次,旋转的角度是当前时间的小时数/12*360。

    需要注意的是:时针、分针和秒针都是围绕表盘的中心点旋转的,通过设置图片的锚点来实现这一效果;

实现代码:

#import "XZClockViewController.h"

@interface XZClockViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *Clock;

@property (weak, nonatomic) IBOutlet UIImageView *hour;

@property (weak, nonatomic) IBOutlet UIImageView *minute;

@property (weak, nonatomic) IBOutlet UIImageView *second;

@property (nonatomic, weak) NSTimer *timer;

@end

@implementation XZClockViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 设置3个针的锚点
    self.hour.layer.anchorPoint = CGPointMake(0.5f, 0.9f);
    self.minute.layer.anchorPoint = CGPointMake(0.5f, 0.9f);
    self.second.layer.anchorPoint = CGPointMake(0.5f, 0.9f);
    
    // start timer
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(tick) userInfo:nil repeats:YES];
    
    // set initial hand positions
    [self tick];
}

- (void)tick {
    
    // convert time to hours,minutes and seconds
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    
    NSUInteger units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    
    NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
    
    CGFloat hoursAngle = (components.hour / 12.0) * M_PI * 2.0;
    
    // calculate hour hand angle
    // calculate minute hand angle
    CGFloat minsAngle = (components.minute / 60.0) * M_PI * 2.0;
    
    // calculate second hand angle
    CGFloat secsAngle = (components.second / 60.0) * M_PI * 2.0;
    
    NSLog(@"%f---------%f----------%f",hoursAngle,minsAngle,secsAngle);
    
    // rotate hands
    self.hour.transform = CGAffineTransformMakeRotation(hoursAngle);
    self.minute.transform = CGAffineTransformMakeRotation(minsAngle);
    self.second.transform = CGAffineTransformMakeRotation(secsAngle);
}

LCD风格的数字方式显示

实现效果:


用简单的像素字体(一种用像素构成字符的字体,而非矢量图形)创造数字显示方式,用图片存储起来,使用图片拼合即使来显示,如下图:

在 xib中创建6个视图,小时、分钟、秒钟各两个,如下图:


如果每一个都用 outlets 对象就会显得太多了,所以,我们就用了一个 OutletCollection 对象把他们和控制器联系起来,这样我们就可以以数组的方式方法视图了。先将第一个view右键拖动到控制器,选择 Outlet Collection,再把右侧五个view,右键拖动到这个 Outlet Collection 中就行。如下图:


代码实现:

#import "XZClockViewController.h"
@interface XZClockViewController ()
@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *digitViews;
@property (nonatomic, weak) NSTimer *timer2;
@implementation XZClockViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 数字时钟页面
    [self numberClock];
}
- (void)numberClock {
    UIImage *digits = [UIImage imageNamed:@"LCDNumber"];
    for (UIView *view in self.digitViews) {
        view.layer.contents = (__bridge id)digits.CGImage;
        view.layer.contentsRect = CGRectMake(0, 0, 0.1, 1.0);
        view.layer.contentsGravity = kCAGravityResizeAspect;
        view.layer.magnificationFilter = kCAFilterNearest;
    }
    
    // start timer
    self.timer2 = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(tick2) userInfo:nil repeats:YES];
    [self tick2];
}

- (void)tick2 {
   NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
    NSUInteger units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    
    NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
    
    // set hours
    [self setDigit:components.hour / 10 forView:self.digitViews[0]];
    [self setDigit:components.hour % 10 forView:self.digitViews[1]];
    
    // set minutes
    [self setDigit:components.minute / 10 forView:self.digitViews[2]];
    [self setDigit:components.minute % 10 forView:self.digitViews[3]];
    
    // set seconds
    [self setDigit:components.second / 10 forView:self.digitViews[4]];
    [self setDigit:components.second % 10 forView:self.digitViews[5]];
}

//
- (void)setDigit:(NSInteger)digit forView:(UIView *)view {
    view.layer.contentsRect = CGRectMake(digit * 0.1, 0, 0.1, 1.0);
}

@end



猜你喜欢

转载自blog.csdn.net/understand_XZ/article/details/80510763
今日推荐