The SafeArea insets are not updated when UITabbar is hidden - ios

I am using the tab bar based app and on detail screen the tab bar is hidden. The issue is when the tab bar is hidden it will still occupy the white space that of tab bar and safeAreaLayoutInsets are not updated. On orientation change or moving from background to foreground it will work.
self.tabBarController.tabBar.hidden = YES;
View hierarchy
UITabbarController
|--UISplitViewController
|--UIViewController (first VC)
|--UINavigationController
|--UIViewController (second VC)
The issue is similar to one reported in Apple Forum

If you need to toggle the tab bar visibility of a visible view, this workaround fixes the layout:
let currentFrame = tabBarController.view.frame
tabBarController.view.frame = currentFrame.insetBy(dx: 0, dy: 1)
tabBarController.view.frame = currentFrame
This code should be executed immediately after the tab bar visibility is changed. It triggers an update of the safe area and a single layout pass of the view. The resizing of the frame is not visible to the user.
It is a workaround and certainly not great, but it works for us and does not seem to have negative side effects. Moreover, I do not expect negative side effects in the future when iOS updates the layout by itself.

Related

Have a view cover entire screen except tab

I am currently trying to create a temporary view that covers the entire window of my app (except the tab bar) while the background threads loads the content. The way I am doing this is the following
super.viewDidLoad()
let window = UIApplication.shared.keyWindow!
let v = UIView(frame: window.bounds)
window.addSubview(v)
However, this creates a view that covers the tab bar. Is there a way to have a view cover the entire screen except the tab bar?
Yes, if you are in a view controller where there is a tab bar (i.e. inside a UITabBarController interface), the top of the tab bar is the bottom of the safe area, so instead of setting the frame to window.bounds, adjust the height of the frame in accordance with where the bottom of the safe area insets are.

View changes sizes when tab is changed

I have a tabBarController with 5 views . The problem is that when I change tabs the view size changes from what it was initially and it messes up my UI. On coming back to the tab, there is also a content offset. I have set the
self.automaticallyAdjustsScrollViewInsets = false but that does not help either.
Here are the outputs to
print(self.view.frame)
When App launches for the first time output is (0.0, 0.0, 320.0, 568.0)
When tab is changed and I come back to the home view, the Output is (0.0, 64.0, 320.0, 455.0)
How can I fix this?
I think your problem is:
When you are running application at that time your view is not considering navigation bar height there for its origin y is 0.0 and when you are changing tab it is detecting navigation bar on screen so view is considering navigation bar above it and takes its origin 64.0 (which is 20.0 status bar and 44.0 navigation bar).
To solve this:
You can set view controller property under top bar Yes/No as per requirement OR you can take one subview and set its frame according to main view frame as per your need in ViewDidLoad or ViewWillAppear.
Hope this might help you. :)

Table view top space to navigation bar increased after pressing back

When I click one of the cells in the table view, it opens a new view with the following code:
let fullResView : FullResponseViewController = self.storyboard?.instantiateViewControllerWithIdentifier("FullResponseView") as! FullResponseViewController
fullResView.receivedPost = post
self.navigationController?.pushViewController(fullResView, animated: false)
When I press back, it increases the distance between the table view and the Top Layout Guide. Representation:
Hierarchy:
I have a tab bar controller, that is embedded in a navigation controller.
The table view is drag & dropped after creating an normal view. So the table view is inside a View.
Table view does contain an header view. When setting a background color for this, it moves together with it, so it should not be anything with those constraints.
constraints for the table view are:
equal with to superview
Align Center X to superview
top space to Top Layout Guide
bottom space to Bottom Layout Guide
I've tried the following:
set this in viewWillAppear:
self.responsesTableView.contentOffset = CGPointMake(0, 0)
self.automaticallyAdjustsScrollViewInsets = false
This did work when I pressed back, then switch to another view in the tab bar, and then switch back again. Without contentOffset it will stay like this forever.
As i seen the OP images that seems like Navigation translucent property Issue. Because after push a viewcontroller there is same 44px white space. so it means if your Navigation translucent property is true then your UITableview start from 0th Y position. And if your Navigation translucent property is false then UITableview start from 44px Y position.
So i guess in between push and back some where UINavigation's translucent become a true and false. make following one line add in your appdelegate class in DidFinish method:
UINavigationBar.appearance().translucent = false
This is appearance of UINavigationBar for make this false globley in your project. Hope that will be fix your issue.
I'm not sure if this is related to your particular issue, but it's worth checking whether your UITableView is the first control on your screen:
Why is there extra padding at the top of my UITableView
Even in the latest version of Xcode, this is a bug. But it's easy enough to fix, if you know how to get around it.

How to hide iOS tabbar and fill the space it leaves

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.

Any quick solution to make a view appear behind the status bar in iOS 7?

I'm porting my app from iOS 6 to IOS 7 (there will eventually be a complete GUI redesign for iOS 7 but in the meanwhile just getting the existing GUI to display properly on iOS 7 is the goal.
I had the issue where the status bar was overlapping my GUI and so have shifted the Y origin of the view controller's view down by 20.
However my app contains a pulldown which when retracted is overlapping with the status bar. In the screenshot the red is a button which is present in the pulldown view. The grey bar is the top of the main view behind which a portion of pulldown is hiding when retracted.
I implemented the pull down as a fixed size child subview of the main view and when retracted its Y origin is a negative number thus it is effectively still displayed but off the top of the screen. When the user pulls it down I just animate the increase in the Y origin until eventually the origin is 0.
Is there some way I can make the pull down view appear beneath the status bar or some other quick solution?
Note of course I can't simply toggle the pulldown's alpha to display/hide it as it pullsdown obviously thus its appearance/disappearance is not a discreen action. I could maybe attempt to make the portion of it that is on top of the status bar invisible but as its something that is moving that seems like its going to be complicated. Is there any simple solution?
Thanks
Add another view, with a fixed position, under the status bar (with the same color of your grey bar), 20px tall and same width of the status bar, but with a z-index higher than the retracting view. This view will cover the retracting view (but not the status bar) acting as a "background" for the status bar itself. Obviously you have to adjust the Y position of the retracting view to make it tappable by the user (but under the status bar)
iOS 7 by default lets views take up the fullscreen, including the status bar. This is controlled using the UIRectEdgeAll property.
If you want the old style view, set UIRectEdgeNone for self.edgesForExtendedLayout
in viewDidLoad:
self.edgesForExtendedLayout = UIRectEdgeNone;

Resources