Reputation: 7227
I ran into the same problem described in this OpenRadar issue. As stated there:
Summary: The hidesBottomBarWhenPushed property of UIViewController doesn't work as expected for apps built with iOS 6 SDK (not beta SDKs for iOS 7). The animation is weird when hiding the bottom bar (e.g. a tab bar).
Steps to Reproduce:
Create a new project with the TabBar template in Xcode 4. Add a UINavigationController to the FirstViewController. Add a button on the FirstViewController and set its action to push a new view controller. (please see the sample code attached)
Run the demo on an iOS 7 beta 5 device.
Press the button, back from the UINavigationController, pay attention to the animated view transitions.
Expected Results: The animation works exactly the same as on an iOS 6 device.
Actual Results: The animation looks weird. The FirstViewController is sliding down from the bottom.
Sample code: http://cl.ly/QgZZ
Is there any way to fix or work around this when building with the iOS 6 SDK?
Upvotes: 0
Views: 2640
Reputation: 1838
In My Case, I had TabBarViewController
with UINavigationController
in each tabs & faced similar issue.
I used,
nextScreen.hidesBottomBarWhenPushed = true
pushViewToCentralNavigationController(nextScreen)
It works fine when nextScreen is UITableViewController subclass & applied auto layout.
But, It does not work fine when nextScreen
is UIViewController
. I found it depends on nextScreen
auto layout constraints.
So I just updated my currentScreen with this code -
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
self.tabBarController?.tabBar.hidden = true
}
In this way you can achieve desired outcome but its not good way to achieve it.
Hope it helps.
Upvotes: 1
Reputation: 15213
This issue definitely exists. I did some investigation and found out what's causing it. When pushing a view controller with UINavigationController
, you view controller's view is contained in a UIViewControllerWrapperView
, which a private Apple's view managed by the UINavigationController
. When the transition animation is about to occur and the hidesBottomBarWhenPushed
is set to YES, this UIViewControllerWrapperView
is being animated with wrong position
for the Y axis, so the solution is just to overwrite this behaviour and give correct values for the animation. Here's the code:
//Declare a property
@property (nonatomic, assign) BOOL shouldFixAnimation;
...
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
#ifndef __IPHONE_7_0 //If this constant is not defined then we probably build against lower SDK and we should do the fix
if (self.hidesBottomBarWhenPushed && [[[UIDevice currentDevice] systemVersion] floatValue] >= 7 && animated && self.navigationController) {
self.shouldFixAnimation = YES;
}
#endif
}
-(void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
#ifndef __IPHONE_7_0
if(self.shouldFixAnimation) {
self.shouldFixAnimation = NO;
CABasicAnimation *basic = (CABasicAnimation *)[self.view.superview.layer animationForKey:@"position"]; //The superview is this UIViewControllerWrapperView
//Just in case for future changes from Apple
if(!basic || ![basic isKindOfClass:[CABasicAnimation class]])
return;
if(![basic.fromValue isKindOfClass:[NSValue class]])
return;
CABasicAnimation *animation = [basic mutableCopy];
CGPoint point = [basic.fromValue CGPointValue];
point.y = self.view.superview.layer.position.y;
animation.fromValue = [NSValue valueWithCGPoint:point];
[self.view.superview.layer removeAnimationForKey:@"position"];
[self.view.superview.layer addAnimation:animation forKey:@"position"];
}
#endif
}
Upvotes: 6