iOS芝麻信用儀表盤效果(一)

整體效果如下


表盤.gif

(一)做出白點(diǎn)旋轉(zhuǎn)效果
大致說一下基礎(chǔ)工作和需求:

基礎(chǔ)工作:UI做好的表盤一個(gè)(可以自己繪制),帶白點(diǎn)的條形圖一個(gè)(我的白點(diǎn)其實(shí)是一個(gè)長條,除了白點(diǎn)其它是透明的,當(dāng)然你可以用一個(gè)白點(diǎn)圍繞著某個(gè)點(diǎn)做旋轉(zhuǎn))

需求:給定一個(gè)分?jǐn)?shù),白點(diǎn)相應(yīng)旋轉(zhuǎn)一定度數(shù),分?jǐn)?shù)顯示的lab值遞增,每達(dá)到20分星星亮一顆,背景色過渡變換,最后一段要求減速。

把整體分割一下,我們要做的動(dòng)畫有這么幾個(gè):

1.白點(diǎn)的旋轉(zhuǎn)
2.分?jǐn)?shù)值的變化
3.背景色的變化
4.減速的體現(xiàn)
5.動(dòng)畫同步

先說1、2、4
材料UI準(zhǔn)備過了(表盤標(biāo)準(zhǔn)圓的一部分這點(diǎn)很重要,不然圓心找不對)。
既然幾個(gè)動(dòng)畫的時(shí)間要同步,那么就要找一個(gè)基準(zhǔn)點(diǎn),圍繞什么來規(guī)劃,這里我選擇了“分?jǐn)?shù)值”(個(gè)人覺得除了分?jǐn)?shù)值其他的做不了參考價(jià)值)。
這里自定義,每增加一個(gè)數(shù)值動(dòng)畫時(shí)間為X,我定義的為0.05,那么總的動(dòng)畫時(shí)間就有了,為0.05 * 分?jǐn)?shù),白點(diǎn)的旋轉(zhuǎn)時(shí)間也就有了依據(jù)。這里挺簡單的不多說。
說一下這個(gè)白點(diǎn)條條的設(shè)置,從圖上可以看出白點(diǎn)在初始位置并不是水平的,說明我們一開始就要它圍繞著圓心偏移一定的角度。
圓心怎么找呢,UI給的圖非常標(biāo)準(zhǔn)這點(diǎn)非常感謝,如圖顯示我的儀表盤


92E26A30-DE88-4F64-9787-E93271165EF6.png

這樣半徑就是圖片的width / 2,圓心就是(width / 2,height - width / 2),然后把白點(diǎn)條條放到圓心上(需要大致調(diào)整一下,因?yàn)橛袟l條有高度),還要注意適配,等比例縮放可以解決
設(shè)置好之后開始設(shè)置圍繞圓心旋轉(zhuǎn),這里需要設(shè)置錨點(diǎn)為(1.0,0.5),角度測一下就OK,因?yàn)榈缺壤s放不會(huì)改變度數(shù),貼一下這段代碼

    self.xuanZhuanView = [[UIImageView alloc] initWithFrame:CGRectMake(-JWScaleY(6.5), JWScaleY(128.5 - 7), JWScaleY(135), JWScaleY(14))];
    _xuanZhuanView.image = [UIImage imageNamed:@"旋轉(zhuǎn)白點(diǎn)"];
    [self addSubview:_xuanZhuanView];
    _xuanZhuanView.layer.anchorPoint = CGPointMake(1, 0.5);
    self.xuanZhuanView.frame = CGRectMake(-JWScaleY(6.5), JWScaleY(128.5 - 7), JWScaleY(135), JWScaleY(14));
    CGAffineTransform transform = CGAffineTransformMakeRotation(-20 * M_PI/180.0);
    [_xuanZhuanView setTransform:transform];

這樣初始狀態(tài)就是這樣的:

BE785070-0740-46DC-AED4-1C29ADAA5304.png

白點(diǎn)的旋轉(zhuǎn)我選擇了CALayer的基礎(chǔ)動(dòng)畫,操作起來清晰簡便,最重要的是它有個(gè)設(shè)置動(dòng)畫速度的屬性,輕松達(dá)到減速效果。這里需要計(jì)算一下需要旋轉(zhuǎn)多少度和一個(gè)臨界值(這里是 9 分,9分以下是負(fù)值,以上是正值),設(shè)置旋轉(zhuǎn)之后位置不恢復(fù)到起始點(diǎn)等屬性。代碼大致如下:

#pragma mark 圓點(diǎn)動(dòng)畫
- (void)yuanDianAnimation {
    [_instrumentView.xuanZhuanView.layer removeAllAnimations];
    CABasicAnimation *roteAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    
    CGFloat rote = 0;
    
    if (grades < 9) {
        rote = -(20 - grades / 100.0);
    } else {
        rote = grades / 100.0 * 220 - 20;
    }
    
    roteAnimation.fromValue = [NSNumber numberWithFloat:-20 * M_PI/180.0];
    roteAnimation.toValue = [NSNumber numberWithFloat:rote * M_PI/180.0];

    //位置不恢復(fù)
    roteAnimation.fillMode = kCAFillModeForwards;
    roteAnimation.removedOnCompletion = NO;
    roteAnimation.duration = animationTime;

    //減速效果
    roteAnimation.timingFunction =
    [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
    
    [_instrumentView.xuanZhuanView.layer addAnimation:roteAnimation forKey:@"rotationAnimation"];
    [_fastTimer setFireDate:[NSDate distantPast]];
}

到目前位置,白點(diǎn)的動(dòng)畫全部完畢,分?jǐn)?shù)遞增的動(dòng)畫勻速的話很簡單,現(xiàn)在要做成漸變的,最后一段要明顯減速,這里需要再做些處理。
這里我用了兩個(gè)計(jì)時(shí)器fastTimer和slowTimer,大致思路如下(如果有更好的方法歡迎提出):

fastTimer負(fù)責(zé)百分之90的分?jǐn)?shù)值遞增,比如80分的話這個(gè)計(jì)時(shí)器方法負(fù)責(zé)0-72之間快速的方法處理,這個(gè)過程速度加快為0.05 * 0.9。然后計(jì)算剩下的時(shí)間和分?jǐn)?shù),得出多少秒需要執(zhí)行一次慢速的方法處理。

這里注意,如果你的視圖有滑動(dòng)視圖的話,因?yàn)镽unLoop的原因需要手動(dòng)將計(jì)時(shí)器加到CommonModes里,不然因?yàn)閙ode的切換影響計(jì)時(shí)器。
代碼大致如下:

#pragma mark 設(shè)置定時(shí)器等事件
- (void)setUpThings {
    animationTime = grades * kTimerInterval;
    self.fastTimer = [NSTimer timerWithTimeInterval:kTimerInterval * kFastProportion target:self selector:@selector(fastTimerAction) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_fastTimer forMode:NSRunLoopCommonModes];
    self.slowTimer = [NSTimer timerWithTimeInterval:(animationTime - kTimerInterval * kFastProportion * grades * kFastProportion) / (grades * (1 - kFastProportion)) target:self selector:@selector(slowTimerAction) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_slowTimer forMode:NSRunLoopCommonModes];
    [_fastTimer setFireDate:[NSDate distantFuture]];
    [_slowTimer setFireDate:[NSDate distantFuture]];
}

#pragma mark 加速定時(shí)器觸發(fā)事件
- (void)fastTimerAction {
    if (labTextNumber == grades) {
        [self.fastTimer invalidate];
        return;
    }
    if (labTextNumber > grades * kFastProportion) {
        [self.fastTimer invalidate];
        [self.slowTimer setFireDate:[NSDate distantPast]];
        return;
    }
    [self actionTimerConmmon];
}

#pragma mark 減速定時(shí)器觸發(fā)事件
- (void)slowTimerAction {
    if (labTextNumber == grades) {
        [self.slowTimer invalidate];
        if (labTextNumber == 100) {
            _instrumentView.starView.starArray[4].image = [UIImage imageNamed:@"實(shí)心星星"];
        }
        return;
    }
    [self actionTimerConmmon];
}

#pragma mark 計(jì)時(shí)器共性事件 - lab賦值 背景顏色變化
- (void)actionTimerConmmon {
    if (labTextNumber % 20 == 0 && labTextNumber != 0) {
        NSInteger index = labTextNumber / 20;
        _instrumentView.starView.starArray[index - 1].image = [UIImage imageNamed:@"實(shí)心星星"];
    }
    if (labTextNumber % 7 == 0 && labTextNumber != 0) {
        NSInteger colorIndex = labTextNumber / 7;
        dispatch_async(dispatch_get_main_queue(), ^{
            [self setUpBackGroundColorWithColorArrayIndex:colorIndex];
        });
    }
    labTextNumber++;
    _instrumentView.gradeLab.text = [NSString stringWithFormat:@"%ld",labTextNumber];
}

到這里,白點(diǎn)和lab的動(dòng)畫就已經(jīng)完成了,星星的動(dòng)畫很簡單不多說了。
這里有個(gè)問題,lab的數(shù)值變化的時(shí)候抖動(dòng)感很強(qiáng)烈,在芝麻信用里感覺不到,知道這個(gè)小bug解決方式的同學(xué)求指導(dǎo)。

個(gè)人原創(chuàng),引用或轉(zhuǎn)載請注明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Core Animation Core Animation,中文翻譯為核心動(dòng)畫,它是一組非常強(qiáng)大的動(dòng)畫處理API,...
    45b645c5912e閱讀 3,165評(píng)論 0 21
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,699評(píng)論 6 30
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,366評(píng)論 25 708
  • 不止從一個(gè)人或者幾個(gè)人口中提到永生233這支鋼筆出奇的好用,再加上這種富有二次元味道的名字,這次終于鼓足勇氣,買了...
    nonozone閱讀 1,023評(píng)論 0 1
  • 圖先生是我相識(shí)的一位朋友,最近發(fā)生一起車禍,因車速過快,車翻了,車?yán)锏膬蓚€(gè)人從車?yán)锱莱鋈ブ?,不到一分鐘,車子起?..
    曠野里的樹兒閱讀 504評(píng)論 3 10

友情鏈接更多精彩內(nèi)容