2012-07-15 103 views
0

我正在開發一個OS X應用程序,其中有一個NSView用於跟蹤連接狀態。如果連接正常,則會顯示一個綠色圓點,如果連接斷開,則會顯示一個紅色圓點。連續核心動畫設計模式

我想使用Core Animation來動畫,但是,在連接狀態變化很快的情況下,我遇到了麻煩。因爲動畫出現在另一個線程中,並且不會阻塞,當我獲得視圖的當前位置時,如果它仍然具有動畫效果,我會在我想要的之間獲得一些東西。

例如,在我的NSView中,我有一個名爲connectionState的@property,我重寫設置狀態併爲綠色和紅色點設置動畫。

- (void)setConnectionState:(BOOL)online 
{ 
    NSPoint newPosition; 
    if (online) { 
     newPosition = NSMakePoint(self.iconView.frame.origin.x, 
           self.iconView.frame.origin.y + 32); 
    } else { 
     newPosition = NSMakePoint(self.iconView.frame.origin.x, 
           self.iconView.frame.origin.y - 32); 
    } 

    [NSAnimationContext beginGrouping]; 
    [[NSAnimationContext currentContext] setDuration:0.5]; 
    [self.iconView.animator setFrameOrigin:newPosition]; 
    [NSAnimationContext endGrouping]; 

    _connectionState = online; 
} 

正如我敢肯定,你可以看到,如果連接狀態的變化迅速,self.iconView.frame是不正確的newPosition最終被對齊。

我想看到的是視圖動畫本身,等到它完成,然後再次動畫自己。

我以爲也許解決方案應該是創建一個隊列,然後在一個線程中不斷添加連接狀態信息到隊列中,然後在後臺有另一個線程,它有一個while(true)語句,排隊,動畫,等待完成,並做到這一點無限。但是,這似乎是一個非常笨重的解決方案。

什麼是解決問題的正確設計模式?

回答

1

似乎是正確的解決辦法是要知道你要根據當前狀態的動畫,而不是使用值的實際值(可能是任何東西)

- (void)setConnectionState:(BOOL)online 
{ 
    const NSPoint kViewOnPosition = {...} ; 
    const NSPoint kViewOffPosition = {...} ; 

    NSPoint newPosition = online ? kOnPosition : kOffPosition ; 

    [NSAnimationContext beginGrouping]; 
    [[NSAnimationContext currentContext] setDuration:0.5]; 
    [self.iconView.animator setFrameOrigin:newPosition]; 
    [NSAnimationContext endGrouping]; 

    _connectionState = online; 
} 
+0

哇,我是過分複雜的事情。這很奇妙。謝謝! – 2012-07-15 21:45:02

+0

樂意幫忙... – nielsbot 2012-07-15 21:49:16

0

不幸的是只有在Mac OS X 10.7上纔有,方法NSAnimationContext可以用來檢測動畫何時完成(所以,在啓動時在某處設置一個標誌,並在處理程序中取消該標誌的設置標記動畫的完成)。通過這種方式,您可以確定在時間段內是否有一些動畫正在進行中,另一個動畫應該啓動。

(我希望有一個更好的辦法,但是這是發生在我身上。)

+0

你建議使用像'NSConditionLock'這樣的'completionHandler'來阻塞線程,直到動畫完成爲止? – 2012-07-15 21:02:08