钟表效果
近期在做一个项目。上面有钟表的显示。
钟表的显示无非用到角度旋转。先看下效果图:
制作步骤例如以下:
先切出四张图:表盘,三个指针(沿着边界切)
代码例如以下: 利用CGAffineTransformMakeRotation顺时针旋转。计算好弧度传入。
//UI
//注意指针的加入顺序
UIImageView *watchImageView =[[UIImageViewalloc]initWithFrame:CGRectMake(0,0,self.width,self.height)];
watchImageView.image =PNGImage(@"watch");
[selfaddSubview:watchImageView];
//由于 CGAffineTransformMakeRotation旋转是以中心点进行旋转,所以要在各个指针下创建一个底部视图,然后把指针放上去,定好位置。使得实现指针旋转效果。
UIView *minuteView = [[UIViewalloc]initWithFrame:CGRectMake((watchImageView.width -6.0)/2.0,0,6.0,160)];
minuteView.backgroundColor =ClearColor;
[selfaddSubview:minuteView];
UIImageView *minuteImageView = [[UIImageViewalloc]initWithFrame:CGRectMake(0,8,6.0,75)];
minuteImageView.image =PNGImage(@"minute");
[minuteViewaddSubview:minuteImageView];
UIView *hourView = [[UIViewalloc]initWithFrame:CGRectMake((watchImageView.width -6.0)/2.0,0,6.0,160)];
hourView.backgroundColor =ClearColor;
[selfaddSubview:hourView];
UIImageView *hourImageView = [[UIImageViewalloc]initWithFrame:CGRectMake(0,18,6.0,65)];
hourImageView.image =PNGImage(@"hour");
[hourViewaddSubview:hourImageView];
UIView *secondView = [[UIViewalloc]initWithFrame:CGRectMake((watchImageView.width -6.0)/2.0,0,6.0,160)];
[selfaddSubview:secondView];
UIImageView *secondImageView = [[UIImageViewalloc]initWithFrame:CGRectMake(0,5,6.0,90)];
secondImageView.image =PNGImage(@"second");
[secondViewaddSubview:secondImageView];
//依据当前时间初始角度
NSDate *today = [NSDatedate];
NSCalendar *greCalendar = [[NSCalendaralloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *dateComponents = [greCalendarcomponents:NSCalendarUnitHour |NSCalendarUnitMinute | NSCalendarUnitSecondfromDate:today];
NSInteger hour = dateComponents.hour;
NSInteger minute = dateComponents.minute;
NSInteger second = dateComponents.second;
if (hour <12) {
_hourAngle = hour/6.0 *M_PI;
}else {
_hourAngle = (hour-12)/6.0 *M_PI;
}
_minuteAngle = minute/30.0 *M_PI;
_secondAngle = second/30.0 *M_PI;
hourView.transform =CGAffineTransformMakeRotation(hourAngle);
minuteView.transform =CGAffineTransformMakeRotation(minuteAngle);
secondView.transform =CGAffineTransformMakeRotation(secondAngle);
//起定时器。每0.05s刷新一次,实现均匀旋转。可是要开启线程,将定时器放进NSRunLoop中。保证主线程有操作时不影响指针旋转
[selfperformSelectorInBackground:@selector(change)withObject:nil];
- (void)change
{
[NSTimerscheduledTimerWithTimeInterval:0.05target:selfselector:@selector(watchRotation)userInfo:nilrepeats:YES];
}
// 计算得知,每0.05s,秒针旋转M_PI/600,分针旋转M_PI/36000。时针旋转M_PI/432000
- (void)watchRotation
{
_secondAngle +=M_PI/600;
if (_secondAngle/2.0 >M_PI) {
_secondAngle =0; //注意归0
}
_watchImageView.secondView.transform =CGAffineTransformMakeRotation(_secondAngle);
_minuteAngle +=M_PI/36000;
if (_minuteAngle/2.0 >M_PI) {
_minuteAngle =0;
}
_watchImageView.minuteView.transform =CGAffineTransformMakeRotation(_minuteAngle);
_hourAngle +=M_PI/432000;
if (_hourAngle/2.0 >M_PI) {
_hourAngle =0;
}
_watchImageView.hourView.transform =CGAffineTransformMakeRotation(_hourAngle);
}
这就哦了。这个能够进行封装。在此就不进行赘述了。
另外。当程序进入后台,指针不再旋转,要想在程序进入前台的时候仍然显示正确的时间。那么在appDelegate的
applicationWillEnterForeground方法中post一个通知,同一时候在钟表页面注冊成为观察者,接收通知。
这样,接收到通知的时候,初始化指针就可以
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
上面的方法存在角度偏差,这个已经測出来。后来的改进方法是,每次确定角度时,依据nscalendar,获取正确的时分秒,又一次计算角度,这样就不会有偏差。我实现的是每隔1s。指针旋转。每次都又一次计算好角度。