app中的進度條就豆蔻年華的少女,充滿着期待感,雖不及花信年華的美麗動人,但也會有不斷成長,不斷進步的驚喜。特別是在大數據的今天,當有數據流動的時候,進度條不僅可以展示數據的進度,而且在不知不覺中已經成爲用戶的一種可能的心理必需品,就像有些汽車公司會刻意的設置關門聲音,具有數據加載完成的提示作用,進度條的速度越快,用戶心理就會感覺越爽,當沒有了進度條,用戶不容易判讀數據加載的情況,如果時間長了,心理難免有波動。而一個好的進度動畫,就像是一個穿長褲美女到短褲美女的過程,有展示到內容的過程,用戶在心理上也不會感到突兀,當然,進度條還是越快越好。下面我們其中的一種進度條的設計方式。
由於沒有找到極致優美進度條的動畫,展示幾張設計圖片:
通過分析,我們發現,結構是圓形加載的設計。很直觀醒目。
在iOS中我們可以通過貝塞爾曲線 + CAShapeLayer畫圖的方式展示這個過程。
實現方式:一個貝塞爾曲線,作爲動畫的路徑,繪製兩個CAShapeLayer圖形,一個作爲背景,一個作爲進度條,通過時間戳控制開始與結束圖像的位置,實現進度動畫。
實現代碼:
1、畫貝塞爾圓與CAShapeLayer圖形
//創建出CAShapelasyer
self.shapeLayer = [CAShapeLayer layer];
//填充顏色
self.shapeLayer.fillColor = [UIColor clearColor].CGColor;
//設置線條的寬度和顏色
self.shapeLayer.lineWidth = 4.0f;
self.shapeLayer.strokeColor = [UIColor orangeColor].CGColor;
//畫貝塞爾曲線//畫出一個園
UIBezierPath *path = [[UIBezierPath alloc] init];
//moveToPoint:去設置初始線段的起點
[path moveToPoint:CGPointMake(250, 100)];
[path addArcWithCenter:CGPointMake(200, 100) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];
self.shapeLayerTwo = [CAShapeLayer layer];
self.shapeLayerTwo.fillColor = [UIColor clearColor].CGColor;
//設置第二條背景線條的寬度和顏色
self.shapeLayerTwo.lineWidth = 8.0f;
self.shapeLayerTwo.strokeColor = [UIColor grayColor].CGColor;
//設置第一條第一條曲線與設定的貝塞爾曲線相同,所以在設定兩條曲線的時候,可以不需要設置大小與位置
self.shapeLayerTwo.path = path.CGPath;
self.shapeLayer.path = path.CGPath;
//設置起始點.保證圈不被顯示出來
self.shapeLayer.strokeStart = 0;
self.shapeLayer.strokeEnd = 0;
//加載
[self.view.layer addSublayer:self.shapeLayerTwo];
[self.view.layer addSublayer:self.shapeLayer];
在其中,還是有注意事項的。
畫圓弧的方法。
// UIBezierPath通過
// - (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise
//
// 可以畫出一段弧線。
// center 圓心的座標 radius半徑 clockwise YES 順時針 startAngle 起始半徑
通過moveToPoint 方法設置初始線段的其實位置,在設置圓的圓心與半徑的時候要根據數據設置。
例如這個例子其實點的x座標,減去圓心的x座標極爲半徑的值,出錯就容易畫不出園。
另外
貝塞爾曲線可以實現不在view的DrawRect方法中畫出一些想要的圖形.DrawRect屬於CoreGraphic框架,佔用CPU,消耗性能大
而該方法通過 CAShapeLayer,CAShapeLayer屬於CoreAnimation框架,通過GPU來渲染圖形,節省性能。動畫渲染直接提交給手機GPU,不消耗內存
2、時間戳的設定
- (IBAction)SetButton:(id)sender {
//間隔時間
float Intervaltime = 0.1;
self.timer = [NSTimer scheduledTimerWithTimeInterval:Intervaltime target:self selector:
@selector(circleAnimation) userInfo:nil repeats:YES];
}
//定時器每次時間到了執行
- (void)circleAnimation{
timeD = 0.1;
//利用定時器控制始位置的方式做動畫。
self.shapeLayer.strokeEnd += timeD;
if (self.shapeLayer.strokeEnd == 1) {
//停止計時器
[self.timer invalidate];
self.timer = nil;
}
}
其中,一個問題就是,我們如何控制進度條的速度,也就是
在實際過程中,進度根據加載情況而定的,那怎麼確定每次加的比例進度呢,數學公式:一般剩餘時間和總時間是有預估的,所以
(剩餘時間 / 總時間) / 每次加載的間隔時間 = 每次加載時間應該加的進度。
所以最終的動畫爲:
另外,也可畫出其他貝塞爾曲線,設計不同風格加載動畫。