TL;DR Update: Basically what I need is to delay my code until iOS finishes its "app startup" animation.
I would like to animate content of a navigation bar when my app becomes active. In my controller, I'm subscribed to UIApplicationDidBecomeActiveNotification
and use setRightBarButtonItem:animated:
to perform the change.
The problem is that the change is not animated.
I did some experimentation and discovered that if I wait a little ([NSThread sleepForTimeInterval:.3]
), it's animating without any issues.
Here is a simple view controller demonstrating the problem:
@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
I'd like find a better solution than blocking the thread or performing the change after a fixed delay.