簡體   English   中英

UIView使用自定義drawRect和animateWithDuration

[英]UIView with custom drawRect and animateWithDuration

我有一個顯示循環進度的UIView子類:

循環進度視圖

上面的屏幕截圖顯示了值為0.667進度。

drawRect:方法中我的UIView子類實現內部我繪制了兩個圓 - 一個用於背景橢圓(灰色),第二個用於實際進度橢圓(藍色)。 (查看源代碼)

它的工作方式與預期相同,但不允許對進度更改進行動畫處理。 我試圖找到允許使用UIViewanimateWithDuration:animations:解決方案animateWithDuration:animations:類方法:

MyCustomView *progressView = ...
[UIView animateWithDuration:3 
                 animations:^{
                     progressView.progressValue = 1.f;
                 }];

但我無法以這種方式制作動畫。

您可以在我的GitHub存儲庫中查看源代碼。

但是,我發現了一種在progressValue發生變化時執行動畫的方法。 這不是我想要的(仍然沒有使用UIViewanimateWithDuration:animations: ,我不確定這是否是正確的方向。 它涉及子類化我的UIView CALayer 您可以在custom_layer分支上查看上面提到的同一個repo中的源代碼。 這是CALayer子類繪圖實現的直接鏈接

我的問題是:有一個基於自定義屬性( progressValue )繪制一些形狀的UIView子類,是否可以使用UIViewanimateWithDuration: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"]strokeEndstrokeEnd為其他任何內容都不會產生任何效果(動畫總是看起來一樣)。

任何我在這里缺少的提示將不勝感激。

更新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 ,並使用strokeStartstrokeEnd ,並fillColor屬性來實現你的效果。 您可能需要兩個shapeLayers,一個在另一個之上,但這種方法的優點是shapeLayer的屬性可以通過CoreAnimation進行動畫處理。

此外,您可以使用這樣的hackery在動畫塊中制作動畫,以及https://gist.github.com/nicklockwood/d374033b27c62662ac8d

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM