UIViews with ambiguous height - ios

I have a collection view inside of a UIView. I need to have the collection view communicate to the UIView the height it should be depending on the amount of content inside the collection view.
I need to then let this UiView (white box) know how tall it should be. I believe I did this part correctly in my setup function, but I'm not certain (I'm new to coding).

I need to have the collection view communicate to the UIView the height it should be depending on the amount of content inside the collection view
That height is the layout's collectionViewContentSize height. But note that this height can grow beyond the size of the window, since this is a scroll view - the whole point is that the size of the content can be greater than the size of the collection view. Thus it might be better to ask yourself why you think you need to do this.

Related

Can we make UIView height always resize with the height of UIStackView inside?

I have a content view (this content view I will use as a subclass of UICollectionViewCell content later) which has an UIStackView inside. Inside that stack view, I add some labels, view. And I calculate some conditions to make sure that when data of a label is empty, that label will be hidden and the stack view will auto change the height and vice versa, if they have data I'll show them and stack view update the height again.
Now I wanna know how can I make the content view height always follow the UIStackView height whenever it's changing.
If you already made your UIStackView to have a dynamic height following its children, then all you need is to add constraints between UIStackView and your content view and it will resize automatically as well.
Now, if you add that content view inside a UICollectionViewCell, then you must make sure to call UICollectionView.reloadData() whenever you change the content of your UIStackView. That way the collection view will recalculate the size and render the cell again. You also have the option to reload a single cell in the collection view if you have a way to determine its indexPath.
Note: Take care of CollectionViewFlowLayout and what size it dictates to the cell. It's recommended that you tell the flow layout the estimated height of your cell via layout.estimatedHeight.

Objective-c: Dynamic size of UIStackView, depending of it's content

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.

ScrollView is Not Appearing

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.

How would I create a UIView with two UIWebViews and another UIView and dynamically change the parent UIView size to contain the content views?

I want to have one big view (probably with scroll). It'll show in vertical:
One HTML string --> 1 webview
Other HTML string --> 1 webview
One view with buttons and labels. (fixed size)
I'd want to calculate the heights of the webviews (in webViewDidFinishLoad) for setting the final size of the parent UIView, but in some cases the height of the parent view will be huge so I guess I'll need a scrollview in this case.
What's the best way for doing this?
Your view structure should look like this.
View Controller -> View -> Scroll View -> View -> All your other stuff.
In your webViewDidFinishLoad method you will want to calculate the height of the content in the UIWebview. Once you have calculated that height set your UIWebview you use that height and reload them. Once the Webview height had been calculated via the content but not applied, you can calculate the total height of all your other stuff.
Take the height of all your other stuff and apply it to your View just inside the scroll view. For scrolling to work you will need to make sure that your scroll view height is actually smaller than the height of it's contents (the view containing all your other stuff).

How can I get a UICollectionView to fill the width of its containing scroll view with Auto Layout without going off the screen?

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

Resources