[英]UIView with custom drawRect and animateWithDuration
我有一個顯示循環進度的UIView
子類:
上面的屏幕截圖顯示了值為0.667
進度。
在drawRect:
方法中我的UIView
子類實現內部我繪制了兩個圓 - 一個用於背景橢圓(灰色),第二個用於實際進度橢圓(藍色)。 (查看源代碼)
它的工作方式與預期相同,但不允許對進度更改進行動畫處理。 我試圖找到允許使用UIView
的animateWithDuration:animations:
解決方案animateWithDuration:animations:
類方法:
MyCustomView *progressView = ...
[UIView animateWithDuration:3
animations:^{
progressView.progressValue = 1.f;
}];
但我無法以這種方式制作動畫。
您可以在我的GitHub存儲庫中查看源代碼。
但是,我發現了一種在progressValue
發生變化時執行動畫的方法。 這不是我想要的(仍然沒有使用UIView
的animateWithDuration:animations:
,我不確定這是否是正確的方向。 它涉及子類化我的UIView
CALayer
。 您可以在custom_layer分支上查看上面提到的同一個repo中的源代碼。 這是CALayer
子類繪圖實現的直接鏈接 。
我的問題是:有一個基於自定義屬性( progressValue
)繪制一些形狀的UIView
子類,是否可以使用UIView
的animateWithDuration:animations:
進行視圖動畫animateWithDuration:animations:
更改視圖的屬性( progressValue
)?
UPDATE
感謝rounak的回答,我擺脫了drawRect:
方法中繪制自定義形狀並創建了兩個單獨的CAShapeLayer
。 我不是每次progressValue
更改時都繪制新的形狀,而只是為這些圖層設置strokeEnd
屬性,它們提供與以前相同的視覺效果,但應該表現更好( 查看源代碼 )。
然后我實現了actionForLayer:forKey:
方法( 檢查源代碼 ),它返回CABasicAnimation
,它應該在progressValue
改變時為strokeEnd
設置動畫。
但是,我仍然遇到動畫問題:
__block NSDate *date = [NSDate date];
[UIView animateWithDuration:3
animations:^{
self.progressView.progressValue = 1.f;
}
completion:^(BOOL finished1) {
NSLog(@"first animation completed in %f", [[NSDate date] timeIntervalSinceDate:date]);
date = [NSDate date];
[UIView animateWithDuration:3
animations:^{
self.progressView.progressValue = 0.f;
}
completion:^(BOOL finished2) {
NSLog(@"second animation completed in %f", [[NSDate date] timeIntervalSinceDate:date]);
[self animateProgress];
}];
}];
我的循環進度視圖為progressValue
更改設置動畫,並執行上面的代碼告訴每個動畫大約需要3秒鍾。 不幸的是,在屏幕上,視圖動畫非常快(動畫在幾分之一秒內完成)。 這是它的樣子:
我不確定問題出在哪里,但我注意到將[CABasicAnimation animationWithKeyPath:@"strokeEnd"]
的strokeEnd
從strokeEnd
為其他任何內容都不會產生任何效果(動畫總是看起來一樣)。
任何我在這里缺少的提示將不勝感激。
更新2
我剛剛注意到動畫實際上是由setProgressValue:
這兩行觸發的setProgressValue:
setter:
self.progressOvalLayer.strokeEnd = MIN(1, MAX(0, progressValue));
self.backgroundOvalLayer.strokeEnd = MIN(1, MAX(0, 1 - progressValue));
( 參見GitHub )
看起來我的actionForLayer:forKey:
實現actionForLayer:forKey:
盡管被執行了,但根本不起作用(用brakepoint檢查)。
我想知道我做錯了什么?
更新 - 解決方案
我試圖為我的UIView
主圖層設置動畫,而不是包含橢圓形狀的自定義圖層。 我需要修復actionForLayer:(CALayer *)layer forKey:
實現使其工作( 檢查固定的源代碼 )。 這解決了我的問題。
我建議你畫一個圓形進度CAShapeLayer
,並使用strokeStart
, strokeEnd
,並fillColor
屬性來實現你的效果。 您可能需要兩個shapeLayers,一個在另一個之上,但這種方法的優點是shapeLayer的屬性可以通過CoreAnimation進行動畫處理。
此外,您可以使用這樣的hackery在動畫塊中制作動畫,以及https://gist.github.com/nicklockwood/d374033b27c62662ac8d
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.