Reference: Add a ScrollView to existing View
I inserted a scroll view into an existing view and now my page is not appearing and I am not sure how to fix this. My scroll view is under the view so I do not understand why it is not displaying.
With auto-layout, the UIScrollView needs to be able to calculate its content size using the available constraints. This is often best accomplished by adding a UIView in the scroll view to act as the content view, rather than directly embedding UIControl subclasses. The content view can then be constrained to be equal width and/or equal height to the parent view of the scroll view. The variable height/width (depending on the scroll direction) of the content view can be calculated by fully constraining the widgets it contains.
Related
I have an UIStackView which is inside a scrollview. the content of the stackView is dynamic, depending of how much views created and added with the methode "addArrangedSubview". if I have a few subviews, there is so much spacing between them, and if I have too much views, they become compressed.
I have:
_viewController
|__ view
|____scrollView
|______stackView (dynamic content)
I set the stackview to:
Alignement: fill
Distribution: equal spacing
Spacing: 5
and of course the constrains top/bottom/leading/trailing
I want to increase the size of the UIStackview every time a view is added, and keep the size of my added subviews.
Maybe something is missing or I have a bad understanding.. someone can explain to me how to do it ?
I'm working with objective-c
I've a detailed Medium post on this topic. You can take a look there for a step-by-step guide. But I'm also adding a brief explanation here as well:
You should have all of the necessary constraints set-up for the scroll view to it's super view. Then comes your stack view that is the sub-view of this scroll view. You might have pinned all the four edges of this stack view to the scroll view as well. But here comes the actual concern.
UIScrollView doesn't work as like other views. It has a contentView. This content view is responsible for scrolling behavior. If there are more content that don't fit in the frame of the scroll view than the scroll is enabled.
So for setting up the content view correctly, the scroll view must know the size of the content view so it knows when to stop scrolling. Here size means the actual width and height. But this size can't be determined from the constraint's setup because they are calculated dynamically by the auto layout engine.
In your case, the stack view acts as the content view of the scroll view. You might have pinned all the edges of the stack view to it's superview - UIScrollView. But that isn't enough for the scroll view to calculate the content size. You must also provide the:
width & height - if your scroll view is scrollable on both axes
width - if you want to scroll vertically and restrict scrolling horizontally
height - if you want to scroll horizontally and restrict scrolling vertically
As you need horizontal scrolling, you must restrict the vertical scrolling by providing the height of the stack view equal to the scroll view (it doesn't always need to be the same height as the scroll view, but should cover the whole height of the scroll view by other means). And you will also need a placeholder x-axis constraint to make the Interface Builder happy. The actual width of the content view will be covered by the sub views that will be added to the stack view.
Important: You should add a Horizontally in Container constraint to the stack view and make this a place holder that will be removed at build time. You can do this by selecting the constraint in the document outline and opening size inspector where you will get a Remove at build time check box. You check that box, you are ready to go.
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
I'm trying to allow the scroll view to adjust size depending on the size of a subview on this page. All of the other constraints for the objects in the picture work fine.
When I add constraints to my subview to hug to the left, right, and bottom of the screen (and the top of the subview hugs to the bottom of the segmented control) and then update frames, it makes the height of the subview 0.
I can't add a height constraint to the subview because the size of the subview will change dynamically depending on the amount of content in it, which will then change the size of the scroll view.
How can I accomplish this without adding a height constraint?
Your view hierarchy should look like :
Create a single child view of the UIScrollView where we will put all
of our content
The content view has to be an explicit size (or a placeholder size in
interface builder and set at run time). In other words your content
view cannot depend on the scroll view to get its size. It can,
however, depend on views outside of the scroll view to get its size.
From Apple Technical Note TN2154
Set translatesAutoresizingMaskIntoConstraints to NO on all views
involved.
Position and size your scroll view with constraints external
to the scroll view.
Use constraints to lay out the subviews within the
scroll view, being sure that the constraints tie to all four edges of
the scroll view and do not rely on the scroll view to get their size.
UIScrollView And Autolayout
Using UIScrollView with Auto Layout in iOS
Try giving the Equl Heights & Equal Width constraints to your Subview.
I have a scroll view. On the scroll view I have added many necessary UILabels and UIButtons etcs.
Now I want to add MORE labels and buttons but I have no room on the interface of the view to add them, otherwise they will overlap the other elements. How do I add more UI elements so that they can be interacted with when the user scrolls? I was thinking if I hold the UIelement over the bottom of the scroll view, the scroll would "scroll down" and present me with more space.
The key thing here is to remember that a view controller's main view in a nib (.xib file or storyboard) is always resized anyway when it is put into the interface. The size you see it at in the nib editor (Interface Builder) is just a "serving suggestion". Thus, SamirChen's answer is quite right: set the view to Freeform so you can resize, and just make it big enough to hold the scroll view which itself is big enough so that you can put in all the desired contents.
I would add just two points that you will find helpful:
Use autolayout outside the scroll view. This will cause the scroll view to become the right size when the view is resized to fit the interface, and will cause everything else to be repositioned correctly.
Use autolayout inside the scroll view too! This is the really cool part. If you set up sufficient constraints between all the contents of the scroll view and the scroll view itself (their superview), the contentSize will be calculated for you automatically using constraints from the inside out! Thus, you don't have to know the content size or set it in code!
It is easier to see than to describe, so download the example code from my book and look at the examples currently entitled "bk2ch07p367scrollViewInNibAutolayout" and "bk2ch07p367scrollViewInNibAutolayout2".
In the Interface Builder, as far as I know, you cannot scroll the Scrollview.
If you just want to add more labels and buttons into your scrollview in the Interface Builder, you can set the size of the View Controller which holds your scrollview to be Freeform in Attribute Inspector. Then you can set the size of the View to any value you want in Size Inspector. After that, you can change your scrollview's size to add more labels and buttons.
"You could design a UIView with all this content on it in a .xib file and make the view whatever size you wanted, then put it into the scroll view in viewDidLoad" referenced from #nhgrif.
Don't forget to change the scroll view's contentSize property to meet the UIView's bounds.
My view heirarchy looks something like this:
- View
- Scroll View
- Collection View
I'm using Auto Layout. The problem is that when I specify that the collection view should take the full width of the superview, it ends up actually taking the full width of the elements contained within it. I.e., if there were 1000 elements in this collection view and each element was 10 pixels wide, the collection view would be 10000 pixels. It appears to ignore my constraints.
The VFL I'm using looks a little like this:
Scroll View
H:|[scroll]|
V:|[scroll]|
Collection View
H:|[collection]|
V:|[collection]|
All views are set to not translate autoresizing masks to constraints.
when I specify that the collection view should take the full width of
the superview, it ends up actually taking the full width of the
elements contained within it.
The whole point of a scroll view is that it permits the display of views that are larger than the scroll view itself. So it doesn't make sense to constrain the collection to the scroll view -- subviews of a scroll view can be as big as they want to be. If you want to limit the size of the collection view, just set its width to whatever width you prefer.
The constraints in your post make the collection view fill the scroll view along both axes. It's not clear why you'd want to do that. I will assume you actually want something like the App Store, which has multiple horizontally-scrolling collections in a vertically-scrolling scroll view.
Auto layout has special behavior for scroll views. Go read Technical Note TN2154: UIScrollView And Autolayout.
So, a constraint between the edge of a scroll view and a descendant of the scroll view affects the scroll view's content size. A constraint between the edge of a scroll view and a view outside the scroll view affects the scroll view's frame.
You need to pin the collection view's left edge to the left edge of your top-level view (the superview of the scroll view), and the right edge similarly. You can't do that with a visual format. You'll need to explicitly create those constraints (or set them up in your xib or storyboard).