Dynamically grow UIView containing a non-scrollable vertical UICollectionView - ios

I am looking for a way to build a UICollectionView with a vertical flow layout that is embedded in a UIView. the UIView acts as the datasource/delegate for the containing collectionview. The behavior I am looking for is that the collectionview itself has its scroll disabled and the containing UIView grows as you add more rows to the collectionview. How can this be achieved?

I think you can achieve this by following steps,
Embed the UIView which you currently have into a UIScrollView(Make its constraint respective to its super view).
Then add height constraint to your UIView and create an outlet for that height constraint in our view controller, so as of now when the height of UIView gets increased the scrollView content size will also get increased.
Then place the UICollectionView inside the UIView and make its top, bottom, left & right constraints to UIView.
Now increase the height constraint constant value based on the number of collection view cells in the collection view.
I hope this will work for your scenario.
But if in case you are free to explain why you need to achieve this kind of behaviour it would be nice, because I cannot able to figure out the need for it.

This kind of scenario could be achieved. Here is rule of the thumb:
You should not specify height of you view, that will be contains unscrollable collection, pinned to it, and it should be embedded in UIScrollView using equals width, and pinned to all sides with margin. Auto layout makes things work.
Otherwise, is there any important reason to disable scrolling and make UIView delegate / data source for collection?

Related

Detect a UIScrollView's height dynamically

I have a real problem with detecting UIScrollView height. I searched a lot and found this solution:
So I dragged from Content View to View and made Equal Height. But I does not work for me.
I also tried to calculate scrollView height according to elements height in it, but I do not think that it's a right way.
How can I set UIScrollView height dynamically? What is the correct way for doing it?
Your ScrollView should add a ContentView like this:
select your scrollView and in size Inspector bottom, set the width like this:
for more details on how to handle scrollView in Interface Builder your can check out this AppleDoc Working with Scroll Views
Hope this help you!
You only way to set height of your scrollView is by calculating the height of individual objects added to scrollview.
Programatically, calculate the height of each UI object and at the end set content height to scrollview.
[scView setContentSize:CGSizeMake(300, height)];
In above line, 'height' is nothing but a sum of all heights of all UI objects calculated.
By doing the below stuff's, I was able to implement UIScrollView with Automatic height based on the contents inside.
Add scrollview to the main view.
Add one ContentView inside this container scroll view.
Give proper constraints inside this content
view to the container scroll view as well as to its internal UI
Components. Please note that you should not give fixed height to the
content View. The constraints of the content view should grow
according to the UI Components inside
This might give you a layout
warning as 'Unambigous.... '. To fix this, give 'Equal Heights' constraint relation between content view and scroll view
Try the above steps, and this will solve your issue :)
Do you want to add item (UIView, UILabel...) in your UIScrollView by auto layout? If so, just put these in it and create correct constraints for them.
The key point is each item which in UIScrollView have top, leading, bottom and trailing side constraints to their superview. Most important is Make Sure that your UIScrollView has top, leading, bottom and trailing Descendant Constraints to its sub-items. It will calculate correct content height of scroll view for you.
In your solution, if your contentView has zero frame, it will not give you any height for scroll view.

What are the correct constraints on UIScrollView from Interface Builder? Pure Autolayout from IB

I have been trying to get ScrollView to work for 2 days now, and it doesn't work at all. Most of the suggestions here on SO and other websites say that you need to pin the ScrollView to the root view and then place a ContentView (UIView) inside ScrollView and then pin it to all sides of the ScrollView (so that the scroll size can determine the contentSize... However this does nothing). There's also conflicting information out there, one video says that there needs to be a constraint from the bottom of the ScrollView to the ContentView. Neither solution has worked for me. Here is what I've been doing in most of the combinations I've tried:
UIView -> UIScrollView
Pin all sides of the UIScrollView to the UIView
Create a UIView (name it content view) and place it inside UIScrollView
Pin all sides of the UIView to the UIScrollView
Problem at this point: UIScrollView needs constraints for X or width AND Y or width. The only thing that seems to solve the complaint is setting the UIView inside the scroll view centered horizontally and vertically, but this does nothing to make scrolling work. Another option is setting the UIView equal height and width to scroll view, but again, that does nothing other than remove the complaint.
I don't understand. Isn't pinning the sides, setting the constraints? IB seems to think that this is not the case.
What are the correct constraints needed? All I need is a simple view with stacked controls (to fill out a form) and the screen needs to be able to scroll if the form is longer than the screen.
I'm using iOS for the first time, and building purely from IB for now... minimal code solution would be best.
You are half way there. First you need to decide what you are going to display in the scrollview, you have placed a content view, that needs to have an intrinsic size. You can choose to put there static or dynamic views. Static views will have their size defined at design time, and that will resolve the UIScrollView AutoLayout constraints. If instead you are doing it at runtime with dynamic views you will need to choose a default size for your content view, create an IBOutlet for the width and/or height of your views and then resize them at runtime altering the outlet in viewDidLayoutSubviews. The video you linked explains that quite clearly.

Dynamic height of UITableView with constraints

I want to make an interface in Storyboard which scales automatically for all iPhone screen sizes as shown in the picture below:
What I want is for view 1 and view 2 to have a constant height, but cover equally much of the horizontal space, and for the UITableView below to stretch all the way up to the UIViews. How can I specify constraints to achieve this effect?
I know how to do this programatically, but I have made it sort of a goal to learn storyboard in this project.
Anybody have any tips?
If you want view1 and view2 to remain fixed at the top, that’s easy enough to do by constraining view1.bottom == tableView.top.
If you want view1 and view2 to scroll with the table view, then put them inside the table view’s header. (To make a header, drag a generic UIView to the space just above the prototype cells in the storyboard editor.) I don’t recommend using constraints to try to make something outside the table view scroll with it, even though that’s (sometimes) possible.
Control-drag from view1 to view2 and create an “equal widths” constraint to divide the space equally.

iOS: animate UICollectionView vertical expansion with constraints?

I've a view controller with a UICollectionView on top (using the default grid layout) followed by other controls below it. As I add / remove cells to / from the collection view, I want it to expand / contract in the vertical direction (so it has enough rows to show all of the cells and no more), and all controls below it to move down / up the screen accordingly. If you imagine how email app UIs work when you add / remove addresses, that's the effect i'm trying to implement. Achieving this effect using constraints, though, is eluding me. Any help would greatly, greatly appreciated!
What I did:
removed all constraints in IB
added a height constraint on the collection view and connected it to an IBOutlet
had IB add missing constraints
add an observer for the collection view's contentSize property
Now, when I add a cell to the collection view and tell it to reload, i'm notified when the contentSize changes and can set the constant for the height constraint to the contentSize height. Result: a collection view that resizes to fill it's content, with the other controls moving up / down as needed :-)

Pure autolayout with a UIScrollView

I'm trying to get a UIScrollView working with autolayout positioning and sizing. I'm following the guidelines for a "Pure Auto Layout Approach" in this documentation, but I'm having a hard time getting it to work.
My hierarchy looks like this:
UICollectionViewCell -> UIView -> UIScrollView -> UIView.
Everything is positioned with autolayout constraints, including the UIScrollView (which is positioned relative to it's direct parent UIView). The UICollectionViewCell does have a fixed size eventually, as it's set by collectionView:layout:sizeForItemAtIndexPath, but I don't think that's relevant this this issue.
The issue I'm having is that the content of the last UIView (the child of the UIScrollView) isn't showing up. If I manually give it a frame size, it does show, but I really want to use autolayout.
There's a line in that documentation article that I don't quite understand:
Position and size your scroll view with constraints external to the scroll view.
Does this indicate that I can use autolayout to position and size the scroll view within it's parent, or does the scrollview have to have a fixed frame?
Autolayout with UIScrollView may seem too complicated at first. Conisder following two things:
1) UIScrollView externally behaves like any another UIView. This means, you can set any position/size to it with auto layout constraints. No differences from UIView.
2) UIScrollView internally CAN (but not should) calculate it's content size basing on given auto layout constraints inside it. For this behavior you should give one odd explicit horizontal & vertical constraint for it.
Say: you has UIView child inside UIView parent. You pin left, top, bottom, right from child to parent. There are ENOUGH constraints, to calculate child's position and size - it's ok.
Now, you do have UIView child inside your UIScollView parent - and the same set of constraints. There are NOT ENOUGH constraints to calculate scroll view's content size. For calculating scroll view's content size, you should set for example equal widths & equal heights constraints for your child to your UIScrollView parent.
Despite you've given not enough info to find your problem out, i think, you most likely didn't set constraints to size/position your UIScrollView inside it's parent. After that - you probably didn't set one more explicit constraint in each direction inside the scroll view to calculate its content size.
I strongly suggest to read ray wenderlich's iOS 6 by tutorials autoalayout parts - you will understand HOW and WHY auto layout works so.
Say you are working with a nib whose size is 568 in height, and the inner view is 650 high.
First make the scroll view the same height as the inner view. Then pin the four sides of the scroll view to its container view, however you will notice that the bottom constraint is a negative number - make this 0.
You will notice that there is a problem with the bottom constraint:
Don't worry, that will be fixed in the next step.
Now pin all four sides of the inner view to that of the scroll view, as well as its width and height:
You will now notice that the previous error has disappeared, and when you run the project, you should now be able to scroll to see the content out of view.

Resources