2009-02-05 43 views
0

我有一個UIImageViews的NSArray,我想循環並快速換出「開」和「關」狀態。我在for循環中編寫了代碼,而不是在用戶點擊UIButton(按鈕的操作)時調用的方法。在一個循環中交換UIImageView圖像

這裏是一個循環:

for(int i = 0; i < [Images count]; i++) { 
    if(i > 0){ 
     [self toggleImageViewOff:[Images objectAtIndex:i - 1]]; 
    } 

    [self toggleImageViewOn:[Images objectAtIndex:i]]; 

    [NSThread sleepForTimeInterval:0.5f]; 
} 

如我所料,我只看到過在「開」狀態的最後的UIImageView用戶界面未更新。我認爲視圖的繪圖更新必須發生在這個代碼也在執行的主線程中。所以我瞭解了performSelectorInBackground:withObject:。使用此方法執行toggleImageViewOn/Off方法使循環正常工作。問題是,如果我讓睡眠間隔太短,我可以在「關閉」之後進行「開啓」更新,而線程操作不按順序。

所以我有一個明智的想法,將睡眠的整個循環移動到它自己的方法中,並使用performSelectorInBackground:withObject:從action方法調用它。我試過了,我回到沒有得到更新的視圖,直到循環結束。

這是一個長篇大論辦法讓我的問題:

什麼是動畫這保證開/關代碼火災的正確順序,並仍然得到視圖更新,即使在高速行駛的最佳方式是什麼? (即非常快速地循環)

我試圖考慮如何使用CoreAnimation來做到這一點,但我似乎無法讓我的頭在如何做到這一點。

對於獎金,這裏的切換方法:

- (void)toggleImageViewOn:(UIImageView *)theImageView { 
    [theImageView setImage:[UIImage imageNamed:@"on.png"]]; 
} 

- (void)toggleImageViewOff:(UIImageView *)theImageView { 
    [theImageView setImage:[UIImage imageNamed:@"off.png"]]; 
} 

回答

0

將循環移動到後臺線程時,您正處於正確的軌道,但是您還需要確保您給主運行循環更新UI的機會。你應該能夠取代以toggleImageViewOn直接調用:和toggleImageViewOff:喜歡的東西

[self performSelectorOnMainThread:@selector(toggleImageViewOn:) withObject:[Images objectAtIndex:i] waitUntilDone:NO]; 

這將做在主線程的UI更新,並沒有等待,直到更新完成你給主運行循環一次機會達到目的。你遇到了像進度條這樣的問題,在循環結束之前它們不會改變,除非你使用上面的UI更新調用從後臺線程進行更新。

0

嘿帕特里克。看看UIImageView的animationImages屬性,以及animationRepeatCount和animationDuration屬性。如果您將開/關圖像放入數組並將其指定爲animationImages屬性,則應該能夠控制重複和持續時間以獲得所需的效果。

希望有幫助!

0

謝謝你。我已經看過了UIIMageView的animationImages屬性。這不正是我想要做的。我在放置在彼此附近的幾個UIImageView之間循環,給人一種印象,即光線在它們之間移動並在它們之間循環。因此,單獨的UIImageView的動畫是彼此分離的,因爲我需要在代碼中根據需要交換圖像。

2

你是否設置了一個動畫上下文(UIView類的方法呢)圍繞這個for循環?沒有它,立即改變而不是動畫。

+0

比爾合理的食譜, 我試圖與周圍循環 [UIView的beginAnimations:@ 「動畫」 上下文:無]。 and [UIView commitAnimations]; 但它沒有效果。我看到的僅僅是循環過程中的一個巨大的停頓,然後「砰」的一聲,只是最後一個圖像是「開」。 – 2009-02-05 20:32:34

+1

hm,imageview不能動畫其'圖像'屬性,我猜想,無賴。您可以考慮在此處使用圖層,因爲它們會對內容中的更改進行動畫製作(默認情況下爲交叉淡入淡出效果)。或者你可以做'推薦'視圖的東西,並添加一個'superview',它可以包含開啓或關閉的圖像視圖 – 2009-02-05 20:43:26

+0

很酷的Bill Dudney現在在這裏。歡迎登上我真的很喜歡你關於iPhone dev的書。 – 2009-02-05 21:54:28

0

調用peformSelectorOnMainThread:withObject:waitUntilDone:從後臺線程上的循環確實更新視圖,我認爲我會永遠需要。我很好奇爲什麼我需要在主線程上執行UIImageView交換?爲什麼不在後臺線程中更改它,然後使用NSThread的sleepForTimeInterval允許主線程更新繪圖呢?

我想我需要去閱讀運行循環和繪圖更新的位置。

非常感謝您的幫助。 (我也會嘗試Bill Dudney的一些額外建議,我認爲這些建議會基於CoreAnimation工作)

1

問題是您沒有給任何UIImages繪製時間。繪圖代碼經過優化,只需繪製所需的內容即可渲染所有這些中間階段。

沉睡的主線程並沒有真正讓它有機會運行。

比爾是正確的,因爲你需要在你的循環周圍設置一個動畫上下文。這將捕獲您所做的所有UIView更改,然後播放它們。最簡單的方法是使用Core Animation。核心動畫「記錄」在UIElemenets中的變化並播放它們。你的代碼(沒有睡眠)在Core Animation塊中可以正常工作。

蘋果有核心動畫on their site