I am getting a really strange animation behaviour when pushing another view controller that has the bottom bar hidden with hidesBottomBarWhenPushed. The first thread I found was that: Strange animation on iOS 7 when using hidesBottomBarWhenPushed in app built targeting <= iOS 6 but as my application is only build and run on iOS7 it is not the case for my problem.
Please see the following video that shows the problem (look in the top right corner):
https://dl.dropboxusercontent.com/u/66066789/ios7.mov
This strange animation shadow only occurs when hidesBottomBarWhenPushed is true.
How can I fix that?
Solved my problem:
self.tabBarController.tabBar.hidden=YES;
In the second view controller is the way to go.
Leo Natan is correct. The reason for this blur effect is because the entire Tab Bar Controller is being animated underneath the navigation controller, and behind that view is a black UIWindow by default. I changed the UIWindow background color to white and that fixed the issue.
hidesBottomBarWhenPushed seems to work great with UITabBars (iOS 7/8).
Turn off the Translucent property of Navigation Bar in Storyboard.
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
}
For more details - https://stackoverflow.com/a/39145355/2564720
An elegant way of doing this, while keeping transparency, is to add this to the root UIViewController:
- (void)viewWillAppear:(BOOL)animated {
[UIView animateWithDuration:0.35f animations:^{
self.tabBarController.tabBar.alpha = 1.0f;
}];
}
- (void)viewWillDisappear:(BOOL)animated {
[UIView animateWithDuration:0.35f animations:^{
self.tabBarController.tabBar.alpha = 0.0f;
}];
}
This way you'll get a nice fade-in/fade-out animation of the tab bar.
What if in the second view controller in viewWillAppear you put
[self.navigationController setToolbarHidden:YES animated:NO];
Related
The issue is simple :
The Application is based on UITabBarViewController
3 Tabs in the controllers
TabBar Views are configured in viewDidLoad for the
UITabBarViewController
On launch, the UIStatusBar appear in Black background color
Changing to any tab the UIStatusBar get colored!
What I'm missing?
I had a similar issue some months ago - I solved it by adding the following lines into my AppDelegate. Please find below my swift code, I'm sure you know the objective-c syntax:
// Setup general NavBar appearance
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
UINavigationBar.appearance().isTranslucent = true
UINavigationBar.appearance().tintColor = UIColor.white
UIApplication.shared.statusBarStyle = .lightContent // => this would be the solution
I think the last line of code would be interesting for you. It's important to set this changes in your AppDelegate.
I had a similar issue. While not directly related the OP's issue with the tab bar, I too saw that my translucent status bar had appeared to turn opaque and was pushing the view down.
After migrating my project from Swift 3 with Xcode 8 to Swift 4 with Xcode 9, I started experiencing this same issue where the status bar appeared to be pushing content down when it was visible. At first I thought it was an issue with the preferred UIStatusBarStyle I had set (I was using UIStatusBarStyleLightContent), but that was working correctly.
The issue was that in the move from Xcode 8 to 9, a subview in one of my view controllers was misplaced in the Storyboard. A constraint that previously pinned that view to the top of the view controller was pointing incorrectly pointing to the View (with margins) instead of the Top Layout Guide. Switching this constraint to use the Top Layout Guide with a value of 0 solved my problem.
In didFinishLaunchingWithOptions method set status bar style to light content
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[application setStatusBarStyle:UIStatusBarStyleLightContent];
and in every viewController return this :
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
or if you are using the UINavigationController then also add this line of code in every viewController (or make a baseViewController) viewWillAppear method
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.navigationBar.barStyle = UIStatusBarStyleLightContent;
For me following approach is working
final class StatusbarStyle {
static let shared = StatusbarStyle()
var style:UIStatusBarStyle = .default
}
and then whenever I need to change status bar color I write following:
StatusbarStyle.shared.style = .default
navigationController?.setNeedsStatusBarAppearanceUpdate()
I have a popover with TabBarController in it. In one tab there is a TableViewController with a list of names. And there is a plus button, that has a modal segue to AddCharacterVC for adding new names.
In iOS 7 I do it like this:
AddCharacterViewController *acvc = (AddCharacterViewController *)segue.destinationViewController;
acvc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
acvc.modalPresentationStyle = UIModalPresentationCurrentContext;// so it does not take full screen in popover
And in AddCharacterVC I set content size like this:
- (void)viewWillAppear:(BOOL)animated {
CGSize size = CGSizeMake(320, 480); // size of view in popover
if (IDIOM == IPAD && [self respondsToSelector:#selector(preferredContentSize)]){
self.preferredContentSize = size;
}
And it works perfectly.
However, in iOS 8 modal view does not cover the whole popover, leaving TabBar visible. The user can tap on it or not, anyway modal view won't unwind properly.
I've tried:
setting acvc.modalPresentationStyle to UIModalPresentationOverCurrentContext
tried to set TabBar hidden
checked in storyboard that edges of TableVC extend under Bottom Bar and Bottom Bar in Modal View (AddCharacterVC) is set to none
All with no results.
Now the only thing I can think of is to try making modalPresentationStyleCustom and use UIPresentationController (I'm trying to do it now, but I haven't done it before). Am I missing something? Could there be other way to do it? Sorry, I cannot post images here yet. Many thanks in advance!
Ok, so I've set the modalPresentationStile to UIModalPresentationCustom, and used UIPresentationController - I've just copied code from WWDC-14's LookInside project and modified it a bit.
I'm not sure if it was the best solution, but it worked in my case.
In my app I have a TabbarController. One of the tabs opens a View which starts the iPhone camera. This CameraView is part of a SDK which is developed by another company. So I can't modify the class of this CameraView.
My problem is that I have to implement a UINavigationBar in this CameraView. I've solved this through a annotationView (this navigationbar is not handled by a navigationcontroller):
[self.annotationView addSubview:navbar];
All works well except the autoresizing matter. If I turn the phone to landscape mode the navigationbar is too short.
I have already tried to set Autoresizingmask but that doesn't help.
Do you have any ideas how I can force the navigationbar to autoresize?
Thanks in advance
Try to adjust the frame of the navigationbar manually, instead of using autorotation.
-willRotateFromInterfaceOrientation:(UIInterfaceOrientation)fio toInterfaceOrientation:(UIInterfaceOrientation)tio
{
if(tio == UIInterfaceOrientationLandscape)
//set navbar frame
else
//...
}
I met with a problem. At first some code from AppDelegate.
- (void)HideMainNavigationBar{
navigCtrl.navigationBarHidden = YES;
}
- (void)ShowMainNavigationBar{
navigCtrl.navigationBarHidden = NO;
}
navigCtrl is my navigation controller.
In my other View Controller I need hide my navigationBar and then show it, to display it correctly.
- (void) moviePlayerWillExitFullScreen:(id)sender {
NSLog(#"exitfullscreen");
AppDelegate *ptr = [AppDelegate SharedAppDelegate];
[ptr HideMainNavigationBar];
[ptr ShowMainNavigationBar];
}
After that, instead of my custom tabBarButton I saw Back button:
After tap ob Back button, it disappears, and I see my navigationBar again with my custom button. This 'bug' was detected in iOS 5.1, on iOS 4.3.2 everithing is ok.
This makes me crazy, help please.
P.S. I know, that I can use:
self.navigationController.navigationBar.frame = CGRectMake(0, 20, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height);
to display navigationBar correctly, but i need to show/hide navigationBar to hide it, while rotating VideoPlayer.
Any ideas?
Wait your answers, thanks.
So, after some manipulations I decided simply to set alpha to my navigationBar.
if (SYSTEM_VERSION_LESS_THAN(#"5"))
[ptr HideMainNavigationBar];
else self.navigationController.navigationBar.alpha = 0;
I hope it would be useful for someone. See ya.
I just have posted code dedicated on UINavigationBar appearance management on github. check out RRViewControllerExtension, it will solve your problem gracefully.
In my app, I got a UINavigationController. Unfortunately, when I rotate the device and the interface orientation changes, the UINavigationBar doesn't change its height. In other iPhone applications, such as the Contacts.app, the navigation bar gets slightly less tall in landscape mode. It must be built-in, because if you take the navigation sample app from the XCode menu and add interface orientation to it, it does change the navigation bar's height properly.
How can I make the navigation bar resize like it does in all other iPhone apps I've seen?
I've done a little testing, and although I don't like the method, it's quite easy to do.
Having looked for a private method that may have worked, I couldn't find one. All I found was:
#property BOOL forceFullHeightInLandscape;
- (BOOL)isMinibar;
There is no setter for -isMinibar, so we can't set that. I guess that it returns a value based on its height. Also, forceFullHeightInLandscape was set to NO, however it still didn't adjust its height.
While changing the autoresizingMask to include UIViewAutoresizingFlexibleHeight, the view did resize to be smaller, but now it was too small. However, -isMinibar suddenly returned YES. So that made me think of just letting the view resize itself, adjusting it to the right height.
So there we go, a method that works, even without private API calls:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self.navigationBar performSelector:#selector(sizeToFit) withObject:nil afterDelay:(0.5f * duration)];
}
One thing you'll have to deal with is that the views below the bar won't get adjusted to the smaller bar, so that there will be a gap between the bar and the views below. Easiest way to solve this is to add a container view, just like the case with a UINavigationController. You'd come up with something like:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self performSelector:#selector(resizeViewsForNavigationBar) withObject:nil afterDelay:(0.5f * duration)];
}
- (void)resizeViewsForNavigationBar {
[self.navigationBar sizeToFit];
// Resize containerView accordingly.
CGRect containerViewRect = self.containerView.frame;
containerViewRect.origin.y = CGRectGetMaxY(self.navigationBar.frame);
containerViewRect.size.height = CGRectGetMaxY(self.view.frame) - containerViewRect.origin.y;
self.containerView.frame = containerViewRect;
}
I think the behavior you want only happens when a navigation controller ( which represents the bars (navigation or toolbar)), is added to the window in the app delegate or presented by a tab bar, etc.
You can add a navigation bar via IB or code, it doesn't mean you have a navigation controller. My opinion is, create a navigation controller and initialize it with the view controller you're working in. Probably when the view rotates, the nav bar will shrink a little, the way you like.
Hope this helps
Thanks to Joost I've added
#property BOOL forceFullHeightInLandscape;
to my custom UINavigationBar class. And set in :
-(id)initWithFrame:(CGRect)frame{
forceFullHeightInLandscape = YES;
Worked like a charm
Similar to Joost's answer, but putting the method in willAnimateRotationToInterfaceOrientation has a better animation effect than willRotateToInterfaceOrientation. (There's no animation delay)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self.navigationBar sizeToFit];
}
I just had this error as well, and although it's probably not for the same reason I'd like to post it here to help anyone else that goofs.
If you're overriding any willRotateToInterface methods, remember to call super
I blanked on that, but once I saw the accepted answer it came to me.
I think this one is kind of similar to you and they have the code snippet:
iPhone: UINavigationBar with buttons - adjust the height
I just tried a few things just within Interface Builder and Xcode and as long as you use the UINavigationBarController as RootViewController it works as described - getting smaller. Did you change any things within the Controller itself or in parts of how the Controller is loaded? Especially concerning the firing of events? I had some bad expiriences with the UITabBarController in terms of breaking the proper messaging and got some 'interessting' view side effects. Just a try and a guess.
(void)viewWillLayoutSubviews {
self.navigationItem.titleView.bounds = self.navigationController.navigationBar.bounds;
}