2009-09-25 159 views
18

我想在UIKit中創建一個自定義的「閃爍遊標」,我嘗試瞭如下所示,有兩個函數基本上保持相互調用,直到光標被隱藏。但是這導致了一個很好的無限遞歸......出於某種原因,這些函數立即互相調用,而不是像預期的那樣每半秒鐘。如何在iphone上閃爍(或閃爍)光標?

我試圖返回,如果「完成」參數不是YES(通過取消註釋「如果(!OK)」線),但沒有導致動畫在所有...

任何更好的主意嗎?我錯過了什麼,是否有更簡單的方法來製作「閃爍的光標」?

- (void)onBlinkIn:(NSString *)animationID finished:(BOOL)ok context:(void *)ctx { 
if (cursorView.hidden) return; 
//if (!ok) return; 
[UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()]; 
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 
[UIView setAnimationDuration:0.5f]; 
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDidStopSelector:@selector(onBlinkOut:finished:context:)]; 
cursorView.textColor = [UIColor grayColor]; 
[UIView commitAnimations]; 
} 

- (void)onBlinkOut:(NSString *)animationID finished:(BOOL)ok context:(void *)ctx { 
if (cursorView.hidden) return; 
[UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()]; 
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 
[UIView setAnimationDuration:0.5f]; 
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDidStopSelector:@selector(onBlinkIn:finished:context:)]; 
cursorView.textColor = [UIColor clearColor]; 
[UIView commitAnimations]; 
} 
+0

上下文參數是一個空指針,而不是一個CGContextRef(雖然傳遞CGContextRef是有效的,它肯定不會是有用的) – rpetrich 2009-09-26 00:11:24

回答

16

在委託:

- (void)blinkAnimation:(NSString *)animationId finished:(BOOL)finished target:(UIView *)target 
{ 
    if (shouldContinueBlinking) { 
     [UIView beginAnimations:animationId context:target]; 
     [UIView setAnimationDuration:0.5f]; 
     [UIView setAnimationDelegate:self]; 
     [UIView setAnimationDidStopSelector:@selector(blinkAnimation:finished:target:)]; 
     if ([target alpha] == 1.0f) 
      [target setAlpha:0.0f]; 
     else 
      [target setAlpha:1.0f]; 
     [UIView commitAnimations]; 
    } 
} 

,並開始動畫:

shouldContinueBlinking = YES; 
[self blinkAnimation:@"blinkAnimation" finished:YES target:cursorView]; 

此外,確保你的類有shouldContinueBlinking實例變量

+2

此外,設置alpha而不是textColor將允許GPU執行所有繪圖並提高性能。類似的,將cursorView設置爲UIView並設置backgroundColor將比UILabel使用更少的RAM和CPU(並且遠小於UITextView或UITextField) – rpetrich 2009-09-26 00:30:19

+0

非常棒!這比我想要的要好得多,並且很容易重用 – 2009-09-26 07:22:40

+0

來自beginAnimations的文檔:context:「在iOS 4.0及更高版本中不鼓勵使用此方法,您應該使用基於塊的動畫方法來指定動畫「。 – drewish 2012-08-01 01:24:51

0

最有可能的,你是阻塞的主要事件循環,因此,阻斷動畫當您嘗試只在完成動畫。

取而代之,設置一個計時器,在1/2秒後觸發下一個動畫。該定時器可以在前一個動畫結束時重置,從而減少負載並使您的閃爍頻率更規則一些(但您必須弄清楚最合適的)。

請參閱NSTimer類的文檔。

請注意,像這樣的任何一種不斷的動畫會對電池造成損耗。沒有龐大的一個,以任何方式,但仍... ...

+0

動畫通常不會持續很長時間,只是用戶使用自定義鍵盤輸入數字的時間......屏幕上有幾個數字,並且軟閃爍的光標應該簡單明瞭地指出正在編輯哪個數字(該數字在自定義視圖中,而不是在文本字段中)。我認爲對電池的影響可以忽略不計(因爲排序時間) – 2009-09-26 07:32:25

+0

Yah--我剛剛提到了電池續航的事情,因爲這是移動平臺上一個有趣的額外考慮因素。 – bbum 2009-09-26 17:12:56

46

做它的核心動畫方式:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
[animation setFromValue:[NSNumber numberWithFloat:1.0]]; 
[animation setToValue:[NSNumber numberWithFloat:0.0]]; 
[animation setDuration:0.5f]; 
[animation setTimingFunction:[CAMediaTimingFunction 
       functionWithName:kCAMediaTimingFunctionLinear]]; 
[animation setAutoreverses:YES]; 
[animation setRepeatCount:20000]; 
[[view layer] addAnimation:animation forKey:@"opacity"]; 

其中查看是您想要眨眼的UIView。核心動畫使得這非常方便,因爲它會自動爲您反轉動畫。請記住,您的完整持續時間是您在持續時間字段中設置的時間的兩倍,因爲您指定的值適用於正向。如果您希望整個動畫在指定的持續時間內運行(向前,然後向後),請將持續時間減半。

+0

太棒了!我的應用中沒有QuartzCore框架,並且不需要它,但這是一個非常好的示例,我將爲未來的程序保持方便。比「UIView方式」更復雜(我發現)。 – 2009-09-26 07:24:49

+2

而不是20000你應該使用HUGE_VALF。然後它永遠重複 – 2014-10-17 10:50:10

+2

@ josema.vitaminew我只希望它重複20K次。永遠會太多。 ;-) – 2014-10-17 15:30:37

2

馬特龍的回答斯威夫特3:

func addOpacityAnimation(view: UIView) { 
    let key = "opacity" 
    let animation = CABasicAnimation(keyPath: key) 
    animation.fromValue = 1.0 
    animation.toValue = 0.0 
    animation.duration = 0.5 
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) 
    animation.autoreverses = true 
    animation.repeatCount = FLT_MAX 
    view.layer.add(animation, forKey: key) 
} 
0
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; 
animation.keyPath = @"opacity"; 
animation.values = @[ @(0.0),@(0.0),@(1.0), @(1.0)]; 
animation.keyTimes = @[ @(0.001),@(0.49),@(0.50), @(1.0)]; 
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
animation.duration = 1.2; 
animation.autoreverses = NO; 
animation.repeatCount= HUGE; 
[layer addAnimation:animation forKey:@"blink"];