I'm having trouble using the space left behind by my hiding a UITabBar.
I have a UITabBarController with a UINavigationController, whose root view controller just has a UIWebView. I'm using auto-layout constraints to make the webview fill the view which works fine (and fills the available space) when I hide the navigation/status bars.
However, when I hide the tab bar (using setNavigationBarHidden), the tab bar is hidden but the space it vacates isn't used up by the webview, as expected.
Searching similar questions suggest using hidesBottomBarWhenPushed before pushing the view. I don't want to have to push another VC (or have to reload the webview) when rotating the device. Others suggest to resize the frame (like https://stackoverflow.com/a/1554637/1429412 ), but I have not been able to do that successfully.
What is the best way to hide the tab bar in one orientation, but not the other, and have a view fill the space vacated by the tab bar?
Portrait screenshot, showing UIWebview with a green background behind status/nav bar and tab bar as expected: http://i.stack.imgur.com/Hzj9k.png
Landscape screenshot showing hidden status/navbar and tab bar. The webview contents have extended to the top (navbar), but not so to the bottom (tab bar). However, the webview itself (the only element with a green background) has extended down just not its contents (regardless of length): http://i.stack.imgur.com/sdk75.png
If I examine the views at runtime (using FLEX), and click the viewable content area, it shows UIWeBrowserView view with shorter 271 height. Clicking the area where the tabbar space is shows _UIWebViewScrollView with the full 320 height. In code, I can see the UIWebView's .contentSize is only 568x271. I tried various combinations of setting the frame on the webview and its subviews, without success.
Right now, without any frame resizing hacks, the code is simply:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[[self navigationController] setNavigationBarHidden:UIInterfaceOrientationIsLandscape(toInterfaceOrientation) animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:UIInterfaceOrientationIsLandscape(toInterfaceOrientation) withAnimation:UIStatusBarAnimationSlide];
self.tabBarController.tabBar.hidden = UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
I'm using xCode 6.1 for an iOS7+ project.
What should I do next? Thanks in advance for any pointers!
That is simply the way Tabbars are suppose to work, The only form of UIView that allows tab bors to be covered are modal views presentviewcontroller .... dismissviewcontroller Apple has a lot of samples just search for it.
Related
Header image with gray bar on top
I am converting our app to fit correctly on newer iOS devices. We are using xib files for the UI. I added a launch screen storyboard to start off the new formatting. I noticed a gray bar across the top of every screen. It is not part of the view controller and I've tried removing the status bar but that only makes the text and icons disappear. I don't think it's the navigation bar either since we have that hidden as well. I have checked the Safe Area Layouts.
Any ideas on what this is and how I can remove it to extend my view all the way to the top? The blue in the image is the color I currently set the background of my view controller and we have a custom header view below that.
Using the View Hierarchy, as suggested, I was able to see the view behind my main view. I inspected the code for that initial view and found the previous developers had offset the Navigation Controller by 20. That is what created the bar on all the views. I have adjusted to remove the offset and it looks perfect now.
I have a UITabBarController which has four tabs. One of those tabs opens a my results screen (a UITableViewController).
On showing this screen, I want to move the UINavigationBar down 20px (to make room for a custom UIStatusBar which I show on all screens).
On all my other screens, I add some code to the viewWillAppear method to change the self.navigationController.navigationBar.frame.origin.y to 20.
but these are all "non-root" screens (i.e. a pushed view with a back button).
However on THIS screen the UINavigationBar must be initially visible, even though it is the root view. I use the same code, but it doesn't move the view down.
I'm assuming autolayout is moving it back into position, so I tried adding this code into viewWillLayoutSubviews and viewDidLayoutSubviews. But when I do this the navigationbar doesn't move down until the first time the tableview is scrolled.
What do I need to do to force the navigationBar to move down (and stay down) before the screen appears?
Are you using storyboards? Set the Y in storyboards to 20, Make your viewcontroller implement UINavigation bar, then add this code:
-(UIBarPosition)positionForBar:(id<UIBarPositioning>)bar{
return UIBarPositionTopAttached;
}
This will tell the app that the navigation bar is to be attached, it will remain at 20px but extend the background all the way up.. So essentially it'll look like it's at y = 20.
I have a strange one that I can not seem to fix. I am currently working on updating my app to iOS7. This all worked in iOS6. It is an universal app and thus uses same xib files. However the iPad uses UISplitViews on some. Like I said, this all worked in iOS6 oh this all works on the iPhone too.
The problem is a grey bar at the bottom. I changed the tab bar to be opaque to move views up properly as i had some UI clipped to bottom of views and that went underneath the tab bar, sidetracked there. But if i set it back to translucent bar, it goes underneath but stretched properly. if i dont, it adds a bar. Other tabs work fine when NOT using splitview.
The UISplitviewController is added programmatically.
See attached image for better description.
This I have tried:
Added autoresize on splitview
Checked xib for subviews in the splitviews to have auto resize
Tried to force splitview to be screen bounds
Removed clips to bounds on all views
Removed autoresize subviews
Any ideas would be welcomed.
Thank you all.
UPDATE:
setting the background colour the uisplitview, it does colour the bar black. So the uisplitview is definitely stretching to it.
I subclassed UISplitViewController and added the line below to viewDidLoad and that fixed the grey line.
self.extendedLayoutIncludesOpaqueBars = YES;
I believe I have found an alternative solution for you. I have had the exact same problem, mostly because we are both doing something against Apple's Guidelines which is having a SplitViewController nested within a Tabbar controller (SplitView should be the root view). This was okay in iOS 5/6, but now in iOS 7 there are far too many side effects to achieve this.
The reason you see your view stretch completely when you set the bar to be translucent is because the bar is NOT taken into account when drawing the view. When you set translucent to false, it is then taken into account of the view and you will see that grey bar there because that's your view pretending there's a tabbar at the bottom of the screen.
And as always, a SplitViewcontroller's height cannot be changed, as it is determined by the visible window height.
I tried everything you did and then some. The real solution came from using a third-party Split View Controller.
I recommend switching over to https://github.com/mattgemmell/MGSplitViewController . This split view controller is actually one large View with container views living inside of it. Because of this, you avoid all the side effects of putting an actual split view controller within a tab bar.
If that doesn't float your boat, you could create your own solution which follows the same idea of having one UIViewController with two container views contained in it, though the people behind MGSplitViewController did a good job of that already.
This was the only way I was able to solve this issue, let me know if you find an alternative.
Instead of creating a subclass for UISplitViewController, I just added this code on my master's viewDidLoad:
self.splitViewController?.extendedLayoutIncludesOpaqueBars = true
For the controller that is the detail view of UISplitViewController you just do this:
-(UITabBarController*)tabBarController{
return nil;
}
I have an issue with the navigation bar.
I have screen with NavBar and opened half transparent view on full screen (it covers NavBar).
Then, if I change device orientation by 180 degree (my app only, for landscape), then NavBar appears on top while animation. NavBar goes back under transparent view after animation completes.
Does somebody face the same issue?
How are you presenting the transparent view? If you are presenting it modally or using a UIPopover, both of these will be removed from the window during the rotation and then added back afterwards.
Have you perhaps tried adding the view as a subview of the window, above the navigation bar, like such?
[self.view.window insertSubview:your_view aboveSubview:self.navigationController.view];
I'm having an issue where the gray overlay that's automatically put over my UISearchDisplayController when the keyboard is shown doesn't always fully cover the table area (you can see the white on the bottom in the picture below). This doesn't always happen but it's frequent enough that it's annoying. Anyone know what's going on? Thanks.
I believe this is a bug in Apple's code. Having worked extensively with UIPopoverControllers, I have found that there are many occasions in which a popover becomes confused as to whether or not it has a navigation bar when performing sizing calculations.
I am confident that if you measure the height of the white box you will find that it is exactly 37 pixels: the height of a navigation bar in a popover. (Navigation bars in popovers are not 44 pixels high like most navigation controllers since they are embedded into the popover's border.)
If you were able to access the gray overlay and manually resize it you could account for the height of the navigation bar or lack thereof. Unfortunately you are in a bit of a bind since the overlay is controlled by the search bar.
My suggestion would be to try to get the popover to recompute the size of its contents after it appears or is resized. I use this pattern when dynamically resizing a UIPopover containing a navigation bar when it appears:
// UIViewController subclass with a navigation bar which is displayed in a popover
// _popoverController is a (unretained) pointer to the UIPopoverController in which this view controller is displayed
- (void)viewDidLoad
{
[self.view sizeToFit];
CGSize newSize; // Dynamically computed based on popover contents
self.contentSizeForViewInPopover = newSize;
newSize.height += 37; // Account for popover navigation bar
[_popoverController setPopoverContentSize:size animated:YES];
}
I don't know how much this answer will help, but I hope it will at least give you a push in the right direction.
Have a look in this post: http://www.cannonade.net/blog.php?id=1498
He discusses the problem, providing a (called by himself) ugly workaround, but also says how to fix it!