I've got a problem with hidesBarOnSwipe
property of UINavigationController
.
Overview :
Link to project file
I have one controller named FirstViewController which is root view of UINavigationController
.
Everything is in Main.storyboard
.
FirstViewController contains UIButton
action. Inside that action I instantiate a SecondViewController and push it on a navigation stack.
- (IBAction)button:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
[self.navigationController pushViewController:vc animated:YES];
}
Inside SecondViewController there is only an hidesBarsOnSwipe
property set to YES
on viewDidLoad
:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.hidesBarsOnSwipe = YES;
}
and dealloc gets NSLogged :
- (void)dealloc {
NSLog(@"Dealloc");
}
Problem :
When we swipe up to hide navigationBar, dealloc is never get called. Instruments shows a SecondViewController memory leak here.
When we are on SecondViewController and we just press back button - everything is fine. Dealloc gets called.
There is definitly some kind of retain cycle but i have no idea why and how to avoid this kind of situation.
Some updates and temporary solution :
There is another method to perform navigationBar hiding. What worked for me is to use :
[self.navigationController setNavigationBarHidden:hidden animated:YES];
To achieve good results add a property in your class to keep track status of navigationBar animation :
@property (assign, nonatomic) BOOL statusBarAnimationInProgress;
Implement UIScrollViewDelegate
like this :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat yVelocity = [scrollView.panGestureRecognizer velocityInView:scrollView].y;
if (yVelocity > 0 && !self.statusBarAnimationInProgress) {
[self setNavigationBarHidden:NO];
} else if (yVelocity < 0 && !self.statusBarAnimationInProgress) {
[self setNavigationBarHidden:YES];
}
}
Set navigation bar hidden should look like :
- (void)setNavigationBarHidden:(BOOL)hidden {
[CATransaction begin];
self.statusBarAnimationInProgress = YES;
[CATransaction setCompletionBlock:^{
self.statusBarAnimationInProgress = NO;
}];
[self.navigationController setNavigationBarHidden:hidden animated:YES];
[CATransaction commit];
}
I use CATransaction to check if animation of navigation bar is completed. Any way that works. Not so easy solution but at least there is no leak :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With