2013-03-06 38 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”,但它被解雇。