View changes sizes when tab is changed - ios

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. :)

Related

The SafeArea insets are not updated when UITabbar is hidden

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.

Unable to put view above navigation bar

I am trying to design a side menu, whose height would be equal to screen height (therefore hiding the navigation bar too). However I am unable to get the same.
I have put constraints as this:
and in viewDidLayoutSubviews()
I have mentioned - sideMenuTopConstraint.constant = -1 * (self.navigationController?.navigationBar.frame.height)!
However I see no change. Also by increasing the height of the side menu view in storyboard, I see that it is always below the nav bar. How do I make it appear above it?
You need to add the view to window as a subview, that should bring this view above the navigation bar as needed.
This is because window is the root of all the views.
UIApplication.sharedApplication().keyWindow?.addSubview(desiredViewHere)

Instantiating view frame so that it fits with navigation bar / tab bar?

I have an app where sometimes views are in navigation controllers, sometimes not, and sometimes in a tab bar and navigation controller.
I create my views programatically using code such as this:
let contact = ContactFormViewController(contactFormView: ContactFormView.init(frame: UIScreen.main.bounds))
however this is causing frames to always be as large as the screen, meaning when there is a navigation bar or tab bar the view is pushed off the visible screen and doesnt fit.
Is there a method to adapt the view height to always show it all on screen regardless of parent elements like the nav bar or tab bar? or would it be a case of always creating views with manual subtractions like this, which seems poor as it needs to assume hardcoded elements:
let attendees = AttendeesViewController(attendeesView: AttendeesView.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height-55)))
thanks for any guidance as its a major issue in my app
The solution was to set the frame to CGRect.zero and then in the init method of the controller, apply layout constraints to the view class to map it to self.view
I think it's wrong to take UIScreen as the reference to lay out your views. I think you should use the content view (the view at the top of your hierarchy) as the reference.

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.

Hidden NavigationBar reappears after app enters foreground

I have a UITableViewController inside a navigationController. I have code that hides the navigationBar (sets its frame.origin.y to a negative value, thereby sending it offscreen) when I scroll the tableView. The navigationBar is successfully hidden, but when I leave the app by tapping the home button and then launch the app into the foreground, the navigationBar is back with frame.origin at (20, 0) (x = 20 since the status bar is visible), and the tableView pushed down the screen (with frame.origin back to (64, 0) in portrait).
Any ideas on how to prevent the navigationBar from reappearing upon the app entering the foreground would be much appreciated.
I think You didn't choose the best practise to hide navigationBar as most of "interal views" are positioned by it's superview automaticaly. The thing is that when you scroll, the navigationBar is moved off the screen...but when the app enters foreground all views are layouted (checkout UIView setNeedsLayout and layoutSubviews) and this moves the novigationBar back to it's position where it belongs to (y=0). There are few other options that you can use:
1) use UINavigationController's setNavigationBarHidden:(animated:) in viewWillAppear: and viewWillDisappear:. More info here SO: how to hide navigationbar when i push from navigation controller?
2) if you want to leave the space behind the navigationBar use (in viewDidLoad or methods from #1):
self.navigationController.navigationBar.alpha = 0;
3) move your code for setting frame in method viewDidLayoutSubviews of you controller (iOS 5+). Every time you scroll in UITableViewControler layoutSubviews method is called (and viewDidLayoutSubviews too). But I wouldn't recommend this solution.
Instead of setting the frame you can use the below code to hide the Navigation bar.
[self.navigationController setNavigationBarHidden:YES];
Hope this will help you. Happy coding :)

Resources