Adding UIViewController with ScrollView and AutoLayout to another UIViewController - ios

I have a UIViewController (added to a UINavigationController) that adds another UIViewController's view using standard code:
[self addChildViewController:toVC];
[self.view addSubview:toVC.view];
[toVC didMoveToParentViewController:self];
That's working fine.
The childViewController's (toVC) view is constructed using Interface Builder and Auto Layout, and it contains a UIScrollView. If I load toVC into my app directly into a UINavigationController (instead of adding it to another view controller) scrolling works perfectly.
However, when adding toVC to my mainVC using the above code, toVC's scrollView doesn't scroll at all and I'm at a loss as to what I need to do.

You should set the frame and the autoresizing mask / auto layout constraints of the child view controller's view. Even though the child controller's view is set up with auto layout, it still needs to be positioned in the parent view controller's view with whatever system the parent controller is using.
EDIT: Another potential issue, since you mentioned that the scroll view doesn't scroll when presented:
Did you set top, left, right, and bottom constraints for the scroll view's subviews? Scroll views treat "space to superview" constraints differently than normal views do; rather than defining where its subview is positioned, these constraints define the content size. Failing to set constraints on both top and bottom, or both left and right, may leave the scroll view with a content size of {0, 0}, in which case the scroll view would not scroll.

Related

IOS9: UIScrollView offset in UINavigationController

This is beyond frustrating. I'm having an issue with the UINavigationController (and thus UINavigationBar) pushing my UIScrollView's content down at the top, similar to the issues found here:
iOS 7 -- navigationController is setting the contentInset and ContentOffset of my UIScrollView
IOS7 : UIScrollView offset in UINavigationController
I tried both the recommended solutions of either setting self.automaticallyAdjustsScrollViewInsets = true in my view controller's viewDidLoad() method and deselecting Adjust Scroll View Insets in the Interface Builder. Both solutions remove the margin at the top, but as a few others have noted, I can't scroll anymore.
The UIScrollView and ContentView fill the entire view controller. My content view (inside the UIScrollView) contains labels, segments, and a UITextView at the bottom. Does it have something to do with the content in Content View?
I can attach pictures if needed. Using XCode 7, Swift 2, and iOS 9.
I solved my issue. In auto layout, I wasn't setting my content view's height constraint.
Previously, I had pinned the bottom of the content view to the view controller that contained the UIScrollView.
I removed that pin and explicitly set the height. It works now.
I just ran into the same issue. I had an "About" view with a bunch of labels containing static text. I had a UIScrollView inside of a view controller and it was being pushed down. I had a label pinned to the bottom of the screen that was being drawn off page when it was not necessary to do that.
I had the following view hierarchy:
View Controller
View
Scroll View
Content View (UIView)
Label
Label
Content View was pinned to the bounds of Scroll View, but the width and height had equal constraints to View.
I resolved this by adding another UIView as a child of View. My hierarchy looks like this now:
View Controller
View
Inner View (UIView)
Scroll View
Content View (UIView)
Label
Label
I set the height constraint on Content View to be equal height to Inner View. This resolved the issue for me and everything started displaying correctly. Inner View is pinned to the borders of View.
NOTE: In the hierarchies, the Labels should be children of Content View. In the preview, it's showing that the Markdown lists can't go that deep.
May or may not apply to you, but if you have a Nav controller and you don't need it to be translucent you can do something along the lines self.navigationController.navigationBar.translucent = NO;
This may help with your odd offsets.

IOS : Make entire view scrollable, not only subview

I have a viewController in which I have a scrollView in which I have 3 views. This is a scheme :
ScrollView (UIScrollView)
Header (UIView)
TabBar (UIView)
Container (UIView in which I load a ViewController)
The main problem is that, in my container (in which there is a view controller), I have a collectionView (which can scroll) but I want my entire scrollView to scroll (not only my container).
So this is what I have :
And this is what I want :
Anyone can help me with this ?
I just solved this problem for my own project. Assuming you are using storyboards, I made the UIView a child of UITableView and made the UITableView extend the full viewport of the device.
Since UITableView implements UIScrollView you get full screen scrolling of your content.
General Rule your parent view has to implement UIScrollView and extend the full screen to get viewport vertical scrolling.
To do this, if you are not using auto layout or if you are adding views to container programmatically, you must manually set collection view frame to match its content size after you load some data on it. If you are using auto layout, you should create height constraint outlet and set its constant value based on collection view content size, again after loading data on it
You should set the frame of the container view to match the height of the view controller that it is loaded in it and set the contentsize of the scroolview based on the container height.
A scrollview will scroll only if its contents are bigger than its frame. This applies to the parent scrollview as well as the child scrollview.
Here in your case, for the parent scrollview to scroll its contents (Header, Tabbar & container) together must have greater height than its parent. The child scrollview (container) is already scrolling because its contents (a view controller) has greater height than its parent.
I have made both scroll views to scroll:
(1) The parent scrollview - by increasing the height of the child scrollview so that it extends below the main view controller's frame. The child scrollview is one of the contents of the main scrollview.
(2) The child scrollview - Setting a large content inside it so that it is bigger than its parent. I have used a long UIImage as its content.
Also, I have used autolayout and pinned the contents to the scrollviews' sides by adding constraints.
Hope this helps.
This is how it scrolls: Scrolling of UIScrollView inside another

Using Auto layout with hidden views

I have a view controller with a UIScrollView. Inside that scrollview I have two UIViews. viewA sits onto of viewB. I am using Xcode 5 and auto layout in this project. What I would like to do is when viewA is hidden, move viewB to the top where viewA was sitting (technically, still sitting, just hidden).
I looked at this SO answer: How to use auto-layout to move other views when a view is hidden?
However it hasn't really helped me. I connected a IBOutlet which was a constant to the vertical spacing to the top of the scroll view and set it to 0.0f when viewA was hidden. However it makes no changes to my UI at all.
First get the Top Space to SuperView NSlayoutConstraints Outlets for both subViews and then do the following:-
[self.aView setHidden:YES];
if([self.aView isHidden])
{
self.bViewTopConstraint.constant = self.aViewTopConstraint.constant;
}
using this the second UiView will go to the place of first UIView.
For Scrollview you have to set the constraints value properly. No need to set any contentsize. Once you set the constriants scrollview will work automatically.
Check the attached screenshot.

Autolayout - Freeform View

I have a UIViewController with a UIView in which I am adding UIViewController views in as subviews. i.e
UIViewController *vc = [[MyViewController alloc] init];
[my_view_in_xib addSubview:vc.view];
The ViewControllers view and the subviews have AutoLayout enabled. The top level does resize correctly (changing background color to red) I can see it is the right size. However in the subviews in the XIB file I have set the view to be "Freeform" or "None" on the "Size" and pinned the tables to top & bottom and made them pin on the width but the height does not seem to auto resize?
Any suggestions?
James
Every time you resize, you should send setNeedsLayout to the superview. Otherwise, the layout system will not recalculate the frames of the subviews.
In Apple's own words:
View resizing primarily occurs when the orientation of your
application’s interface changes but it may happen at other times as
well. For example, calling the setNeedsLayout method forces your view
to update its layout.

After resizing view inside UIScrollView, the scroll view does not know it changed

I resized the view that I put into a UIScrollView, but the scroll view does not know that the size changed.
So, I tried removing the view and re-adding it to the UIScrollView, but that did not help.
How can I convince the UIScrollView that its contents have changed size?
Thanks.
Did you remember to set the content size of the UIScrollView (using [scrollview setContentSize:]) to the new size? The scroll view doesn't figure it out on its own, you have to tell it what the size of its content is.
If the scrollview is a subview of another view and you resized that view (the parent of the scrollview) the scrollview will not actually get resized unless you have set autoresizesSubviews property of the parent view. You will also have to set the autoresizingMask of the scrollview as well.
If you prefer to manually layout the subviews (still assuming the scroll view is a subview of some parent view), you can implement layoutSubviews in the parent view to change the size/position of the subviews when the size of the parent view changes.

Resources