<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      iOS 繪制一個表盤時鐘,秒針效果可以“掃秒/游走”

      最近自己 也嘗試寫了一個表盤時鐘,初衷源于等車時候一個老奶奶問時間,我打開手機,時間數(shù)字對我來說相對敏感,但是老奶奶是看不清的,我想識別 還是看表盤 老遠(yuǎn) 看時針分針角度就可以識別當(dāng)前時間。

      于是我想寫一個表盤時鐘。

           效果圖:

           

            基本原理,基本邏輯和其他時鐘大同小異:定時器 repeat 獲取當(dāng)前時分秒,計算旋轉(zhuǎn)角度,渲染UI。

            幾個注意的關(guān)鍵點,重點,難點。

      一.旋轉(zhuǎn)角度

          以表盤為圓心,即 時針分針秒針繪制的矩形UI 錨點 anchorPoint. (默認(rèn)錨點 是矩形中心點 anchorPoint(0.5,0.5)))

          //時鐘偏轉(zhuǎn)角度
          CGFloat hoursAngle = (components.hour / 12.0) * M_PI * 2.0;
          //分鐘偏轉(zhuǎn)角度
          CGFloat minsAngle = (components.minute / 60.0) * M_PI * 2.0;
          //秒鐘旋轉(zhuǎn)角度
          CGFloat secsAngle = (components.second / 60.0) * M_PI * 2.0;
          CGFloat prevSecAngle = ((components.second - 1) / 60.0) * M_PI * 2.0;

          

       position 和 anchorPoint 關(guān)系:

       (1)position是layer中的anchorPoint在superLayer中的位置坐標(biāo)。

       (2)position與anchorPoint是處于不同坐標(biāo)空間中的重合點,修改重合點在一個坐標(biāo)空間的位置不影響該重合點在另一個坐標(biāo)空間中的位置

       (3)公式

          frame.origin.x = position.x - anchorPoint.x * bounds.size.width;
          frame.origin.y = position.y - anchorPoint.y * bounds.size.height;

      二.秒針是否“掃秒或游走秒針”

         每秒一動的秒針效果:

         起初使用了

         self.secondHandImageV.transform = CGAffineTransformMakeRotation(secsAngle);

        游走秒針使用:

       

       //提前存儲秒針layer的初始位置
              [self.secondHandImageV.layer removeAnimationForKey:@"transform"];
              CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:@"transform"];
              ani.duration = 1.f;
               ani .removedOnCompletion= NO;
              //ani.delegate = self;
              ani.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(prevSecAngle , 0, 0, 1)];
            
              ani.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(secsAngle , 0, 0, 1)];
              [self.secondHandImageV.layer addAnimation:ani forKey:@"transform"];

         因為一個事layer層的變化 一個不是,當(dāng)兩種秒針效果在真機中切換的時候 總會閃動 原因參見參考2 

         于是需要及時修改layer層的聯(lián)動變化添加了

      ani.delegate = self;
      
      #pragma mark -CAAnimationDelegate
      - (void)animationDidStart:(CAAnimation *)anim
      {
          //防止layer動畫閃動
          self.secondHandImageV.layer.transform = CATransform3DMakeRotation (self.secondAngel, 0, 0, 1);
          //NSLog(@"animationDidStart%@",self.secondHandImageV.layer.animationKeys);
          
      }
      - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
          //防止layer動畫閃動
          self.secondHandImageV.layer.transform = CATransform3DMakeRotation (self.secondAngel, 0, 0, 1);
          //NSLog(@"animationDidStop%@",self.secondHandImageV.layer.animationKeys);
      }

      三.時針分針動一下時候de效果

          期初都是滿足條件 1秒直接跳到下一個位置,但是在“掃描/游走秒針”效果下,仿佛臨界的跳動狀態(tài)不具有一致性,于是在“掃描/游走秒針”狀態(tài)下,時針 分針 添加一個1s de animation.  整體臨界效果就自然了

      整體timer 定時任務(wù)如下:

      #pragma mark -- 定時任務(wù)
      - (void)tick {
          // NSCalendarIdentifierGregorian : 指定日歷的算法
          NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
          // NSDateComponents封裝了日期的組件,年月日時分秒等(個人感覺像是平時用的model模型)
          // 調(diào)用NSCalendar的components:fromDate:方法返回一個NSDateComponents對象
          // 需要的參數(shù)分別components:所需要的日期單位 date:目標(biāo)月份的date對象
          // NSUInteger units = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;//所需要日期單位
          NSDateComponents *components = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:[NSDate date]];
          //時鐘偏轉(zhuǎn)角度
          CGFloat hoursAngle = (components.hour / 12.0) * M_PI * 2.0;
          //分鐘偏轉(zhuǎn)角度
          CGFloat minsAngle = (components.minute / 60.0) * M_PI * 2.0;
          //秒鐘旋轉(zhuǎn)角度
          CGFloat secsAngle = (components.second / 60.0) * M_PI * 2.0;
          CGFloat prevSecAngle = ((components.second - 1) / 60.0) * M_PI * 2.0;
          
          self.secondAngel = secsAngle ;
          
          if (self.isWanderSecond) {
              //提前存儲秒針layer的初始位置
              [self.secondHandImageV.layer removeAnimationForKey:@"transform"];
              CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:@"transform"];
              ani.duration = 1.f;
              ani .removedOnCompletion= NO;
              ani.delegate = self;
              ani.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(prevSecAngle , 0, 0, 1)];
            
              ani.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(secsAngle , 0, 0, 1)];
              [self.secondHandImageV.layer addAnimation:ani forKey:@"transform"];
          } else {
              [self.secondHandImageV.layer removeAnimationForKey:@"transform"];
              self.secondHandImageV.layer.transform = CATransform3DMakeRotation (secsAngle, 0, 0, 1);
              //self.secondHandImageV.transform = CGAffineTransformMakeRotation(secsAngle);
          }
          //
          if (self.isWanderSecond && self.isContinuous) {
              [UIView animateWithDuration:1.0 animations:^{
                  self.hourHandImageV.transform = CGAffineTransformMakeRotation(hoursAngle);
                  self.minuteHandImageV.transform = CGAffineTransformMakeRotation(minsAngle);
              }];
          } else {
              self.isContinuous = YES;
              self.hourHandImageV.transform = CGAffineTransformMakeRotation(hoursAngle);
              self.minuteHandImageV.transform = CGAffineTransformMakeRotation(minsAngle);
          }
      }

       

      github地址 TimeClock

       

      參考

       

      1.https://www.jianshu.com/p/2f8962055f21 (layer層 中 position 和 anchorPoint  關(guān)系)

      2. https://blog.csdn.net/mydo/article/details/51553982

      posted on 2019-01-21 16:56  ACM_Someone like you  閱讀(1032)  評論(0)    收藏  舉報

      導(dǎo)航

      主站蜘蛛池模板: 中文字幕乱码一区二区免费| 亚洲精品一区久久久久一品av| 日本一区二区三区四区黄色| 亚洲最大有声小说AV网| 白嫩少妇激情无码| 丰满人妻熟妇乱又伦精品劲| 亚洲高清无在码在线无弹窗| 久久精品国产精品亚洲精品| 国产二区三区不卡免费| 亚洲中文无码手机永久| 亚洲精品国产精品国在线| av一区二区中文字幕| 伊人久久大香线蕉av五月天| 国产成人精品无人区一区| 日韩人妻一区中文字幕| 最新亚洲人成网站在线观看| 亚洲免费视频一区二区三区 | 免费中文熟妇在线影片| 精品人妻无码中文字幕在线| 国产一区二区三区精品综合| 狠狠躁夜夜躁人人爽天天古典| 中文字幕不卡在线播放| 中国少妇人妻xxxxx| 无码日韩精品一区二区三区免费 | 欧美视频二区欧美影视| 伊人久久大香线蕉综合影院| 国产精品一区二区小视频| 久久不见久久见免费视频观看| 农村老熟妇乱子伦视频| 亚洲电影在线观看| 国产黄色精品一区二区三区| 亚洲av日韩av综合在线观看| 日本视频一区二区三区1| 秋霞电影院午夜无码免费视频| 黑人巨大videos极度另类| 日韩精品无码区免费专区| 人妻少妇精品视频二区| 丝袜国产一区av在线观看| 亚洲色在线v中文字幕| 日本一区不卡高清更新二区 | 亚洲熟妇精品一区二区|