利用 UIView
的 transform
函数 CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle)
该方法需要传入一个角度值的参数,所以需要实时获取当前时间的时分秒数值,这里参考用 NSCalendar
日历类来获取相关数值,然后还需要一个 UIView
的实例变量,当然如果想要秒针动起来,NSTimer
也是必不可少的。
当然,首先需要几张图片。时钟指针图片来自 阿里巴巴矢量图库, 表盘来自百度。
pt_hour.png
pt_minute.png
pt_second.png
直接上代码,首先需要背景表盘与三根时钟指针
@interface LayerClockViewController ()
@property (nonatomic, strong) UIImageView *imgClock;
@property (nonatomic, strong) UIImageView *hourHand;
@property (nonatomic, strong) UIImageView *minuteHand;
@property (nonatomic, strong) UIImageView *secondHand;
@end
这里偷懒了,imgClock
做了懒加载,指针一起处理了。
- (UIImageView *)imgClock
{
if(!_imgClock) {
CGPoint point = self.view.center;
_imgClock = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 250, 250)];
_imgClock.center = point;
[self.view addSubview:_imgClock];
_secondHand = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
_secondHand.center = point;
_secondHand.layer.anchorPoint = CGPointMake(0.5, 0.9);
[self.view addSubview:_secondHand];
_minuteHand = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
_minuteHand.center = point;
_minuteHand.layer.anchorPoint = CGPointMake(0.5, 0.9);
[self.view addSubview:_minuteHand];
_hourHand = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
_hourHand.center = point;
_hourHand.layer.anchorPoint = CGPointMake(0.5, 0.8);
[self.view addSubview:_hourHand];
}
return _imgClock;
}
注意属性 anchorPoint
的作用,为视图添加锚点,不加这行代码的话,转起来会比较酸爽。
然后是钟表视图添加图片
- (void)drawClock
{
CALayer *layerClock = [[CALayer alloc] init];
layerClock.frame = CGRectMake(0, 0, self.imgClock.frame.size.width, self.imgClock.frame.size.height);
layerClock.contents = (__bridge id)[UIImage imageNamed:@"clock_bg"].CGImage;
[self.imgClock.layer addSublayer:layerClock];
CALayer *layerHour = [[CALayer alloc] init];
layerHour.frame = CGRectMake(0, 0, 100, 100);
layerHour.contents = (__bridge id)[UIImage imageNamed:@"pt_hour"].CGImage;
[self.hourHand.layer addSublayer:layerHour];
CALayer *layerMinute = [[CALayer alloc] init];
layerMinute.frame = CGRectMake(0, 0, 100, 100);
layerMinute.contents = (__bridge id)[UIImage imageNamed:@"pt_mimute"].CGImage;
[self.minuteHand.layer addSublayer:layerMinute];
CALayer *layerSecond = [[CALayer alloc] init];
layerSecond.frame = CGRectMake(0, 0, 100, 100);
layerSecond.contents = (__bridge id)[UIImage imageNamed:@"pt_second"].CGImage;
[self.secondHand.layer addSublayer:layerSecond];
}
最后就是角度的获取了
- (void)timeFire
{
NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierChinese];
NSCalendarUnit unit = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *components = [calendar components:unit fromDate:[NSDate new]];
CGFloat hourAngal = ((CGFloat)labs(components.hour-12)/12)*2*M_PI; //先转成12小时制
CGFloat minuteAngal = ((CGFloat)components.minute/60)*2*M_PI;
CGFloat secondAngal = ((CGFloat)components.second/60)*2*M_PI;
self.hourHand.transform = CGAffineTransformMakeRotation(hourAngal);
self.minuteHand.transform = CGAffineTransformMakeRotation(minuteAngal);
self.secondHand.transform = CGAffineTransformMakeRotation(secondAngal);
}
这里用 components.hour
获取当前小时,是24小时制的,看了下 NSDateComponents
类,没有找到设置时间格式为12小时的属性,暂时只能这么处理下。(若有好的方法请不吝赐教)
最后愉快的调用就好了
- (void)viewDidLoad {
[super viewDidLoad];
[self drawClock];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeFire) userInfo:nil repeats:YES];
[self timeFire]; //手动调用一次的主要目的是首次显示当前的时钟,不然会先显示12点,1秒后转到正确时间。
}
为了保证界面的流畅性,需要先手动调用一下 timeFire
。
看看效果:
clock.gif
效果还行,仔细看时针指的位置是不对的,按理说应该在靠近6点的位置才对,核对下代码后发现
CGFloat hourAngal = ((CGFloat)labs(components.hour-12)/12)*2*M_PI;
时针的角度只是处理了小时,没有把分钟的算进去,同理分钟的指针也没有把秒计算在内。
把分钟加进去
CGFloat hourAngal = ((CGFloat)fabs((components.hour-12)+((CGFloat)components.minute/60))/12)*2*M_PI;
效果就比较理想了
clock_new.gif
感谢爱抽烟的芭比提供的 iPhoneSimulator
的录屏代码
xcrun simctl io booted recordVideo filename.mov
以及KFAaron
提供的 .mov
转 .gif
的方法,可惜自己在用 brew
安装 ffmpeg
的时候一直报错,texi2html
下载地址无法访问,开关 vpn 都不好使,只好作罢
==> Installing dependencies for ffmpeg: texi2html, yasm, x264, lame, xvid
==> Installing ffmpeg dependency: texi2html
==> Downloading http://download.savannah.gnu.org/releases/texi2html/texi2html-5.
==> Downloading from http://ftp.yzu.edu.tw/nongnu/texi2html/texi2html-5.0.tar.gz
curl: (7) Failed to connect to ftp.yzu.edu.tw port 80: Operation timed out
Error: Failed to download resource "texi2html"
Download failed: http://ftp.yzu.edu.tw/nongnu/texi2html/texi2html-5.0.tar.gz
最后只好放弃,用了 GIF Brewery 3 墙裂推荐,功能很强大,使用也很方便。
网友评论