iOS仿支付寶芝麻信用分數(shù)儀表盤動畫效果
先看看效果圖:

儀表盤動畫效果.jpg
1.圓環(huán)上綠點的旋轉(zhuǎn)
2.分數(shù)值及提示語的變化
3.背景色的變化
直接上主要代碼:
1.自定義ZLDashboardView儀表盤文件:
.h 文件:
/** * 根據(jù)躍動數(shù)字 * * 確定百分比 * 現(xiàn)在的跳動數(shù)字——>背景顏色變化 * */ #import <UIKit/UIKit.h> @interface ZLDashboardView : UIView @property (nonatomic, strong) UIImage *bgImage; @property (nonatomic, copy) void(^TimerBlock)(NSInteger); /** * 躍動數(shù)字刷新 * */ - (void)refreshJumpNOFromNO:(NSString *)startNO toNO:(NSString *)toNO; @end
.m 文件
#import "ZLDashboardView.h"
#import "UIView+Extensions.h"
#define degreesToRadians(x) (M_PI*(x)/180.0) //把角度轉(zhuǎn)換成PI的方式
static const CGFloat kMarkerRadius = 5.f; // 光標直徑
static const CGFloat kTimerInterval = 0.03;
static const CGFloat kFastProportion = 0.9;
static const NSInteger MaxNumber = 1000;
@interface ZLDashboardView () {
CGFloat animationTime;
NSInteger beginNO;
NSInteger jumpCurrentNO;
NSInteger endNO;
}
// 百分比 0 - 100 根據(jù)躍動數(shù)字設(shè)置
@property (nonatomic, assign) CGFloat percent;
@property (nonatomic, strong) CAShapeLayer *bottomLayer; // 進度條底色
@property (nonatomic, assign) CGFloat lineWidth; // 弧線寬度
@property (nonatomic, strong) UIImageView *markerImageView; // 光標
@property (nonatomic, strong) UIImageView *bgImageView; // 背景圖片
@property (nonatomic, assign) CGFloat circelRadius; //圓直徑
@property (nonatomic, assign) CGFloat startAngle; // 開始角度
@property (nonatomic, assign) CGFloat endAngle; // 結(jié)束角度
@property (nonatomic, strong) UILabel *showLable; // 跳躍數(shù)字
@property (nonatomic, strong) UILabel *markedLabel; // 提示語
@property (nonatomic, strong) NSTimer *fastTimer;
@property (nonatomic, strong) NSTimer *slowTimer;
@property (nonatomic, assign) NSInteger intervalNum;
@end
@implementation ZLDashboardView
#pragma mark - Life cycle
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.circelRadius = self.frame.size.width - 10.f;
self.lineWidth = 2.f;
self.startAngle = -200.f;
self.endAngle = 20.f;
// 尺寸需根據(jù)圖片進行調(diào)整
self.bgImageView.frame = CGRectMake(6, 6, self.circelRadius, self.circelRadius * 2 / 3);
self.bgImageView.backgroundColor = [UIColor clearColor];
[self addSubview:self.bgImageView];
//添加圓框
[self setupCircleBg];
//光標
[self setupMarkerImageView];
//添加躍動數(shù)字 及 提示語
[self setupJumpNOView];
}
return self;
}
- (void)setupCircleBg {
// 圓形路徑
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.width / 2, self.height / 2)
radius:(self.circelRadius - self.lineWidth) / 2
startAngle:degreesToRadians(self.startAngle)
endAngle:degreesToRadians(self.endAngle)
clockwise:YES];
// 底色
self.bottomLayer = [CAShapeLayer layer];
self.bottomLayer.frame = self.bounds;
self.bottomLayer.fillColor = [[UIColor clearColor] CGColor];
self.bottomLayer.strokeColor = [[UIColor colorWithRed:206.f / 256.f green:241.f / 256.f blue:227.f alpha:1.f] CGColor];
self.bottomLayer.opacity = 0.5;
self.bottomLayer.lineCap = kCALineCapRound;
self.bottomLayer.lineWidth = self.lineWidth;
self.bottomLayer.path = [path CGPath];
[self.layer addSublayer:self.bottomLayer];
// 240 是用整個弧度的角度之和 |-200| + 20 = 220
// [self createAnimationWithStartAngle:degreesToRadians(self.startAngle)
// endAngle:degreesToRadians(self.startAngle + 220 * 1)];
}
- (void)setupMarkerImageView {
if (_markerImageView) {
return;
}
_markerImageView = [[UIImageView alloc] init];
_markerImageView.backgroundColor = [UIColor clearColor];
_markerImageView.layer.backgroundColor = [UIColor greenColor].CGColor;
_markerImageView.layer.shadowColor = [UIColor whiteColor].CGColor;
_markerImageView.layer.shadowOffset = CGSizeMake(0, 0);
_markerImageView.layer.shadowRadius = kMarkerRadius*0.5;
_markerImageView.layer.shadowOpacity = 1;
_markerImageView.layer.masksToBounds = NO;
self.markerImageView.layer.cornerRadius = self.markerImageView.frame.size.height / 2;
[self addSubview:self.markerImageView];
_markerImageView.frame = CGRectMake(-100, self.height, kMarkerRadius, kMarkerRadius);
}
- (void)setupJumpNOView {
if (_showLable) {
return;
}
CGFloat width = self.circelRadius / 2 + 50;
CGFloat height = self.circelRadius / 2 - 50;
CGFloat xPixel = self.bgImageView.left + (self.bgImageView.width - width)*0.5;//self.circelRadius / 4;
CGFloat yPixel = self.circelRadius / 4;
CGRect labelFrame = CGRectMake(xPixel, yPixel, width, height);
_showLable = [[UILabel alloc] initWithFrame:labelFrame];
_showLable.backgroundColor = [UIColor clearColor];
_showLable.textColor = [UIColor greenColor];
_showLable.textAlignment = NSTextAlignmentCenter;
_showLable.font = [UIFont systemFontOfSize:100.f];
_showLable.text = [NSString stringWithFormat:@"%ld",jumpCurrentNO];
[self addSubview:_showLable];
// 提示語
_markedLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPixel, CGRectGetMaxY(_showLable.frame), width, 30)];
_markedLabel.backgroundColor = [UIColor clearColor];
_markedLabel.textColor = [UIColor greenColor];
_markedLabel.textAlignment = NSTextAlignmentCenter;
_markedLabel.font = [UIFont systemFontOfSize:20.f];
_markedLabel.text = @"營養(yǎng)良好";
[self addSubview:_markedLabel];
}
#pragma mark - Animation
- (void)createAnimationWithStartAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle { // 光標動畫
//啟動定時器
[_fastTimer setFireDate:[NSDate distantPast]];
// 設(shè)置動畫屬性
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.calculationMode = kCAAnimationPaced;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.duration = _percent * kTimerInterval;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
pathAnimation.repeatCount = 1;
// 設(shè)置動畫路徑
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path, NULL, self.width / 2, self.height / 2, (self.circelRadius - kMarkerRadius / 2) / 2, startAngle, endAngle, 0);
pathAnimation.path = path;
CGPathRelease(path);
[self.markerImageView.layer addAnimation:pathAnimation forKey:@"moveMarker"];
}
#pragma mark - Setters / Getters
/**
* 開始動畫 確定百分比
*
*/
- (void)refreshJumpNOFromNO:(NSString *)startNO toNO:(NSString *)toNO {
beginNO = 0;//[startNO integerValue];
jumpCurrentNO = 0;//[startNO integerValue];
endNO = [toNO integerValue];
_percent = endNO * 100 / MaxNumber;
NSInteger diffNum = endNO - beginNO;
if (diffNum <= 0) {
return;
}
if (diffNum < 100) {
_intervalNum = 5;
} else if (diffNum < 300) {
_intervalNum = 15;
} else if (diffNum <= MaxNumber) {
_intervalNum = 10;
}
NSLog(@"數(shù)字間隔:%ld",_intervalNum);
//數(shù)字
[self setupJumpThings];
// 設(shè)置角度
NSInteger angle = 0;
NSInteger num = [toNO floatValue] - [startNO floatValue];
if (num < 200) {
angle = self.startAngle + 220 * (num / 200.0) / 5.0;
} else if (num < 350) {
angle = self.startAngle + 220 / 5.0 + (3 / 5.0 * 220) * (num - 200) / 150.0;
} else {
angle = self.startAngle + 220 / 5.0 * 4 + (220 / 5.0) * (num - 350) / 250.0;
}
//光標
[self createAnimationWithStartAngle:degreesToRadians(self.startAngle)
endAngle:degreesToRadians(angle)];
}
- (void)setBgImage:(UIImage *)bgImage {
_bgImage = bgImage;
self.bgImageView.image = bgImage;
}
- (UIImageView *)bgImageView {
if (nil == _bgImageView) {
_bgImageView = [[UIImageView alloc] init];
}
return _bgImageView;
}
#pragma mark - 躍動數(shù)字
- (void)setupJumpThings {
animationTime = _percent * kTimerInterval;
self.fastTimer = [NSTimer timerWithTimeInterval:kTimerInterval*kFastProportion
target:self
selector:@selector(fastTimerAction)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_fastTimer forMode:NSRunLoopCommonModes];
//時間間隔 = (總時間 - 快時間間隔*變化次數(shù))/ 再次需要變化的次數(shù)
//快時間
NSInteger fastEndNO = endNO * kFastProportion;
NSInteger fastJump = fastEndNO/_intervalNum;
if (fastJump % _intervalNum) {
fastJump++;
fastEndNO += _intervalNum;
}
CGFloat fastTTime = fastJump*kTimerInterval*kFastProportion;
//剩余應(yīng)跳動次數(shù)
NSInteger changNO = endNO - fastEndNO;
NSInteger endJump = changNO / _intervalNum + changNO % _intervalNum;
//慢時間間隔
NSTimeInterval slowInterval = (animationTime - fastTTime) / endJump;
self.slowTimer = [NSTimer timerWithTimeInterval:slowInterval
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 加速定時器觸發(fā)事件
- (void)fastTimerAction {
if (jumpCurrentNO >= endNO) {
[self.fastTimer invalidate];
return;
}
if (jumpCurrentNO >= endNO * kFastProportion) {
[self.fastTimer invalidate];
[self.slowTimer setFireDate:[NSDate distantPast]];
return;
}
[self commonTimerAction];
}
#pragma mark 減速定時器觸發(fā)事件
- (void)slowTimerAction {
if (jumpCurrentNO >= endNO) {
[self.slowTimer invalidate];
return;
}
[self commonTimerAction];
}
#pragma mark 計時器共性事件 - lable賦值 背景顏色及提示語變化
- (void)commonTimerAction {
if (jumpCurrentNO % 100 == 0 && jumpCurrentNO != 0) {
NSInteger colorIndex = jumpCurrentNO / 100;
dispatch_async(dispatch_get_main_queue(), ^{
if (self.TimerBlock) {
self.TimerBlock(colorIndex);
}
});
}
NSInteger changeValueBy = endNO - jumpCurrentNO;
if (changeValueBy/10 < 1) {
jumpCurrentNO++;
} else {
// NSInteger changeBy = changeValueBy / 10;
jumpCurrentNO += _intervalNum;
}
_showLable.text = [NSString stringWithFormat:@"%ld",jumpCurrentNO];
if (jumpCurrentNO < 350) {
_markedLabel.text = @"營養(yǎng)太差";
} else if (jumpCurrentNO <= 550) {
_markedLabel.text = @"營養(yǎng)較差";
} else if (jumpCurrentNO <= 600) {
_markedLabel.text = @"營養(yǎng)中等";
} else if (jumpCurrentNO <= 650) {
_markedLabel.text = @"營養(yǎng)良好";
} else if (jumpCurrentNO <= 700) {
_markedLabel.text = @"營養(yǎng)優(yōu)秀";
} else if (jumpCurrentNO <= 950) {
_markedLabel.text = @"營養(yǎng)較好";
}
}
@end
在所需的當前控制器里展示:
//
// ViewController.m
// ZLDashboard
//
// Created by qtx on 16/9/19.
// Copyright © 2016年 ZL. All rights reserved.
//
#import "ViewController.h"
#import "ZLDashboardView.h"
#import "ZLGradientView.h"
#import "UIView+Extensions.h"
#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define MinNumber 350
#define MaxNumber 950
@interface ViewController ()
@property (nonatomic, strong) ZLDashboardView *dashboardView;
@property (nonatomic, strong) ZLGradientView * gradientView;
@property (nonatomic, strong) UIButton * clickBtn;
@property (nonatomic, strong) UISlider * slider;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//創(chuàng)建背景色
[self setupGradientView];
//創(chuàng)建儀表盤
[self setupCircleView];
//添加觸發(fā)動畫的點擊button
[self addActionButton];
//改變value
[self addSlideChnageValue];
}
- (void)addActionButton {
UIButton *stareButton = [UIButton buttonWithType:UIButtonTypeCustom];
stareButton.frame = CGRectMake(10.f, self.dashboardView.bottom + 50.f, SCREEN_WIDTH - 20.f, 38.f);
[stareButton addTarget:self action:@selector(onStareButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[stareButton setTitle:@"Start Animation" forState:UIControlStateNormal];
[stareButton setBackgroundColor:[UIColor lightGrayColor]];
stareButton.layer.masksToBounds = YES;
stareButton.layer.cornerRadius = 4.f;
[self.view addSubview:stareButton];
_clickBtn = stareButton;
}
- (void)addSlideChnageValue {
CGFloat width = 280;
CGFloat height = 40;
CGFloat xPixel = (SCREEN_WIDTH - width) * 0.5;
CGFloat yPixel = CGRectGetMaxY(_clickBtn.frame) + 20;
CGRect slideFrame = CGRectMake(xPixel, yPixel, width, height);
UISlider *slider = [[UISlider alloc] initWithFrame:slideFrame];
slider.minimumValue = MinNumber;
slider.maximumValue = MaxNumber;
slider.minimumTrackTintColor = [UIColor colorWithRed:0.000 green:1.000 blue:0.502 alpha:1.000];
slider.maximumTrackTintColor = [UIColor colorWithWhite:0.800 alpha:1.000];
/**
* 注意這個屬性:如果你沒有設(shè)置滑塊的圖片,那個這個屬性將只會改變已劃過一段線條的顏色,不會改變滑塊的顏色,如果你設(shè)置了滑塊的圖片,又設(shè)置了這個屬性,那么滑塊的圖片將不顯示,滑塊的顏色會改變(IOS7)
*/
[slider setThumbImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];
slider.thumbTintColor = [UIColor cyanColor];
[slider setValue:0.5 animated:YES];
[slider addTarget:self action:@selector(slideTap:)forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider];
_slider = slider;
}
- (void)slideTap:(UISlider *)sender {
CGFloat value = sender.value;
NSLog(@"%.f",value);
}
- (void)setupGradientView {
self.gradientView = [[ZLGradientView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.gradientView];
}
- (void)setupCircleView {
self.dashboardView = [[ZLDashboardView alloc] initWithFrame:CGRectMake(40.f, 70.f, SCREEN_WIDTH - 80.f, SCREEN_WIDTH - 80.f)];
self.dashboardView.bgImage = [UIImage imageNamed:@"backgroundImage"];
[self.view addSubview:self.dashboardView];
}
- (void)onStareButtonClick:(UIButton *)sender {
if (sender.selected) {
[self.gradientView removeFromSuperview];
self.gradientView = nil;
[self.dashboardView removeFromSuperview];
self.dashboardView = nil;
[self setupGradientView];
[self setupCircleView];
[self.view bringSubviewToFront:self.clickBtn];
[self.view bringSubviewToFront:_slider];
}
sender.selected = YES;
CGFloat value = _slider.value;
NSString *startNO = [NSString stringWithFormat:@"%d", MinNumber];
NSString *toNO = [NSString stringWithFormat:@"%.f",value];//@"693"; 950
NSLog(@"endNO:%@",toNO);
[self.dashboardView refreshJumpNOFromNO:startNO toNO:toNO];
__block typeof(self)blockSelf = self;
self.dashboardView.TimerBlock = ^(NSInteger index) {
[blockSelf.gradientView setUpBackGroundColorWithColorArrayIndex:index];
};
}
@end
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
iOS常用算法之兩個有序數(shù)組合并(要求時間復(fù)雜度為0(n))
這篇文章主要介紹了iOS常用算法之兩個有序數(shù)組合并(要求時間復(fù)雜度為0(n)),實現(xiàn)思路是先將一個數(shù)組作為合并后的數(shù)組, 然后遍歷第二個數(shù)組的每項元素,需要的朋友可以參考下2019-07-07
iOS開發(fā)之路--微博OAuth授權(quán)_取得用戶授權(quán)的accessToken
本文是IOS開發(fā)之路系列文章的第二篇,講訴的內(nèi)容是如何使用微博OAuth授權(quán),并付源碼,然后詳細講解了取得用戶授權(quán)的accessToken,希望對大家有所幫助2014-08-08
iOS中滑動控制屏幕亮度和系統(tǒng)音量(附加AVAudioPlayer基本用法和Masonry簡單使用)
這篇文章主要介紹了iOS中滑動控制屏幕亮度和系統(tǒng)音量(附加AVAudioPlayer基本用法和Masonry簡單使用)的相關(guān)資料,需要的朋友可以參考下2016-12-12
IOS網(wǎng)絡(luò)請求之AFNetWorking 3.x 使用詳情
本篇文章主要介紹了IOS網(wǎng)絡(luò)請求之AFNetWorking 3.x 使用詳情,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02

