I have a UIScrollView added and positioned via Interface Builder, as part of a view controller on a navigation controller stack. When I push a new view controller onto the stack, then pop that new view controller, the UIScrollView in the original view has drifted upwards by exactly 52 pixels.
This ONLY happens on the device, and not the Simulator.
Any ideas what might be causing this? I can fix it retroactively with calls to re-position in the viewWillAppear/viewWillAppear, but for some reason on a very few occasions even this doesn't work, so I'd really like to fix the root cause. Thanks!
Note in response to comments: I'm hiding the navigation bar in the pushed view controller, but not the original view controller. Also note that there are several other UIView elements on the original view controller, but it's only the UIScrollView which is moving out of position.
Update: not hiding the navbar in the pushed view controller has no impact on the UIScrollView problem - but thanks for the suggestion, commenters.
Fix: if the navigation bar is being hidden on a view controller, and you don't want any subviews (which you added via Interface Builder) automatically re-positioning in unexpected ways, make sure the struts on the subviews are set to be fixed.
Related
I am trying to add subview to UITabBar which should be behind other UITabBar Subviews.
I added the subview like this in my subclass of UITabBarController:
self.tabBar.addSubview(CustomTabBarController.xView!)
and then I send it to back as below:
self.tabBar.sendSubview(toBack: CustomTabBarController.xView!)
Problem is it doesn't go back and always appear infront. Also, even when this is the case, I am able to tap on tabbaritems. Is something wrong with UITabBar properties? or else, What am I doing wrong?
A view that a subview of view A can't be behind view A. Think of a subview as being on the page of it's parent view.
It's also likely that a tab bar does not allow you to add subviews to it. Apple's UI controls are usually built to fully manage their view hierarchies, and the results of trying to insert subviews or otherwise mess with the view hierarchy are often undefined.
If you want a view to be behind another view the two views need to have the same parent view. You need to tell the tab bar's superview to add your new view behind the tab bar:
self.tabBar.superview. insertSubview(CustomTabBarController.xView!,
belowSubview: self.tabBar)
Also note that your use of force-unwrapping is ill-advised
EDIT: Small update to my issue, what i did as a solution for now was obviously just having my scrollview white. This fixes my issue, but my real curiosity was to why exactly the content view was doing what i explained below. Also still curious to what common practice formatting is when adding a scroll view to a VC with a navigation bar.
So i am a bit confused with what is going on here. I have a VC with a navigation bar at the top and i need to add a Scroll view to it. So when i did that i stretched it to just below the navigation bar at the top of the screen, then added constraints. (I also made the ScrollView background red so i could differentiate it from the content view)
Secondly i added a UIView which i named Content view and i stretched it to the exact same position as the Scroll view. Then added constraints for that as well. (No objects were added yet)
I then ran the app to check how it looked and i noticed that under the navigation bar my there was a big chunk of red, meaning the Scroll view was full screen in the correct position right below the nav bar, but my content view was not.
A couple things i did to fix this was
I extended the Scroll view all the way to the top of the VC, past the nav bar, but when i ran the app i could see red behind the nav bar, which i figured meant it was not right.
I extended just the content view to the top of the VC, but this did not seem right to me either, even though both seemed to fix the problem.
So my questions are:
When adding views in general to a VC with a nav bar at the top should i be extending those views only to the bottom of the nav bar, or all the way to the top of the VC?
I am new to Scroll views as this is my first time dealing with one, am i missing something in this situation? Or doing something wrong?
Your help is greatly appreciated, thank you.
1) Move the scroll view all the way up and beyond nav bar.
2) Have the scroll view match the height of its parent.
I have a UICollectionView that scrolls with a bunch of images and I want to have a pinned Navigation Bar on the top that stays there even as you scroll. I moved the cell down in the UICollectionView in order to make room for a navigation bar and I dragged one into the View. I can see it in my story board however it is just a black view when I run the app. Can anyone please show me how to make this nav bar appear and how to make it stay pinned at the top even as you scroll. Thank you so so much. (I tried to attach photos of my problem but it says I do not have enough reputation to post images) I hope you guys are able to understand my problem and direct me in a way in which I could add a navigation bar that stays pinned on the top of a CollectionViewController
Drag a navigation controller into your storyboard. You probably want to position it just to the left of the view controller that has the collection view.
Delete the view controller that Xcode automatically attaches to the navigation controller.
Right click on the navigation controller and drag from root view controller over to your view controller where you have your collection view.
If necessary, move all segues that went to the collection view to the navigation controller instead.
I'm having a really strange behaviour. When my app starts everything is fine: the size of the views on screen are exactly the one specified in the storyboard. But just as I try to push a view controller its contents are scaled, so when I pop back the view is messed up.
Any clues?
First learn about Autolayout. Here is a good way to go
Autolayout
Second I am giving you a trick which may work.
Click on viewController
If you don't want your views to extend their edges to bottom or to the top deselect Under top bars and Under Bottom bars
I don't know why UITableView has bottom inset automatically despite I make UITabBarController be hidden by calling [setHidden:YES] before.
The view controller who has UITableView is a child of UITabBarController. I already know that automaticallyAdjustsScrollViewInsets helps any UIScrollView get proper 'contentInset' depending on status of it's container view controller.
So, I expected that UITableView's bottom contentInset will be 0 if UITabBar is hidden. But, doesn't do that.
Although automaticallyAdjustsScrollViewInsets is YES, should I manually adjust that value when UITabBar is hidden?
Tab bars have never been meant to be hidden - after all why have a UITabBarController if you want to hide the tab bar. In the documentation, you are warned not to modify the tab bar object directly:
You should never attempt to manipulate the UITabBar object itself
stored in this property.
This is exactly what you are doing when setting it to hidden.
In iOS6 this has worked, but now in iOS7, it doesn't. And it seems very error prone to hide it. When you finally manage to hide it, if the app goes to the background and returns, Apple's layout logic overrides your changes. There are many such triggers.
My suggestion is to change your design. Perhaps display the data modally.
Putting this here for anyone who gets this problem for nested view controllers.
My view controller containment hierarchy is:
UINavigationController
|--UIViewController
|--UITabBarController
|--UIViewController
The last view controller has a UITableView whose scrollIndicatorInsets keep getting offset by the tab bar controller's UITabBar height even if it is hidden.
Solution: Set automaticallyAdjustsScrollViewInsets to false in the view controller that contains the tab bar controller (and is inside the UINavigationController). No need to set additional properties in the tab bar controller itself and the second view controller where the UITableView is.