2013-03-06 39 views
2

TL; DR更新:基本上我需要的是延遲我的代碼,直到iOS完成其「應用程序啓動」動畫。UIApplicationDidBecomeActiveNotification和setRightBarButtonItem:動畫:

我想在應用程序變爲活動狀態時爲導航欄的內容添加動畫。在我的控制器中,我訂閱了UIApplicationDidBecomeActiveNotification並使用setRightBarButtonItem:animated:執行更改。

問題是,變化沒有動畫。

我做了一些實驗,發現如果稍等一下([NSThread sleepForTimeInterval:.3]),它的動畫效果沒有任何問題。

這裏是說明該問題的簡單視圖控制器:

@interface TESTViewController() 

@property (strong, nonatomic) IBOutlet UINavigationBar *navigationBar; 

@end 

@implementation TESTViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    UINavigationItem *item = [UINavigationItem new]; 
    UIBarButtonItem *oldItem = [[UIBarButtonItem alloc] initWithTitle:@"Old" style:UIBarButtonItemStyleBordered target:nil action:NULL]; 
    [item setRightBarButtonItem:oldItem]; 
    [[self navigationBar] setItems:@[item] animated:NO]; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActiveNotificationAction:) name:UIApplicationDidBecomeActiveNotification object:nil]; 
} 

- (void)applicationDidBecomeActiveNotificationAction:(NSNotification *)notification 
{ 
    // [NSThread sleepForTimeInterval:.3]; 
    UIBarButtonItem *newItem = [[UIBarButtonItem alloc] initWithTitle:@"New" style:UIBarButtonItemStyleBordered target:nil action:NULL]; 
    [[[self navigationBar] items][0] setRightBarButtonItem:newItem animated:YES]; 
} 

@end 

我想找到比阻塞線程或執行的固定延遲後的變化的更好的解決方案。

+0

應用程序在視圖出現之前變爲「活動」 - 爲什麼不簡單地將動畫代碼從'applicationDidBecomeActiveNotificationAction'移動到'viewDidAppear'。 – 2013-03-06 17:08:57

+2

@rokjarc我很樂意。事情是,當我切換回應用程序時,「viewDidAppear:」沒有被調用。順便說一下,'viewDidAppear:'這個名字有點令人誤解(參見http:// stackoverflow。COM /問題/ 5417318/viewdidappear - 不燒不斷再-後的應用程序 - 進入 - 前景)。 – 2013-03-06 17:16:29

+0

啊,是的。我知道我在前一段時間看到了一個解決方法。我相信它與'UINavigationController'有關(即使它沒有在視圖層次結構中使用)。將嘗試找到它。 – 2013-03-06 17:22:37

回答

4

只需在主隊列上使用dispatch_after而不是調用
+[NSThread sleepForTimeInterval:]類的方法。

將你的動畫作爲一個塊傳遞,它應該完美地工作。

+1

是的,這應該有效,因爲更改將在_later_中執行 - 這意味着在下一個更新週期中。這只是一種解決方法,但由於這與內部實現有關,所以沒有正確的方法來做到這一點。 – Tricertops 2013-03-09 21:55:31

+0

這實際上並不是一種解決方法;它確實比使用'[NSThread sleepForTimeInterval:]'好得多,因爲它不會阻塞UI線程。在轉換方面有很多次,有必要延遲一小段時間以允許進行中的動畫完成,以便動畫可以正確啓動(並在適當的位置)。和'dispatch_after()'(或者'[obj performSelector:withObject:afterDelay:]')是不阻塞的。 – 2013-03-10 03:27:06

+0

增加了TL; DR更新。 – 2013-03-15 13:34:33

-1

只需在您的applicationDidBecomeActiveNotificationAction:方法中手動撥打viewDidAppear:即可。將您的動畫代碼放在viewDidAppear:方法中。希望這可以幫助。

0

發佈通知時,我不使用您的方法。

我使用:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeButton) name:@"changeButton" object:nil]; 在接收端。

而且有關消息結束,我打電話 [[NSNotificationCenter defaultCenter] postNotificationName:@"changeButton" object:nil];

試試你的代碼移動到方法:

-(void)changeButton{

UIBarButtonItem *newItem = [[UIBarButtonItem alloc] initWithTitle:@"New" style:UIBarButtonItemStyleBordered target:nil action:NULL];

[[[self navigationBar] items][0] setRightBarButtonItem:newItem animated:YES]; 

}

希望這有助於!

0

您是否試過執行SelectorAfterDelay?

嘗試這樣:

- (void)applicationDidBecomeActiveNotificationAction:(NSNotification *)notification{ 
    [self performSelector:@selector(yourAnimationAction) withObject:nil afterDelay:1]; 
} 

- (void)yourAnimationAction{ 
    //Set your NavAnimation here 
    [self.navigationItem setRightBarButtonItem:theItem animated:TRUE]; 
} 

只要改變延遲,以滿足您的應用程序喚醒延遲...也許這將需要的效果?

0

嘗試將 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActiveNotificationAction:) name:UIApplicationDidBecomeActiveNotification object:nil];改爲viewDidLoad:方法。我認爲對象未被註冊爲「UIApplicationDidBecomeActiveNotification」,但它被解僱。