Adaptive Layout - calculate second row of views based on view width - ios

I am programmatically adding a dynamic number of UIButton which are labeled as hashtags to a compact view using Adaptive Layout. Is there a way for adaptive layout to automatically calculate when the width of the view is met and a new line is needed, or do I need to calculate that myself, then manually anchor the next row of buttons under the previous and so on?
My current source gives me the following image, where a second row is needed. Appreciate any direction on this.

Auto layout cannot do this, so if you want to use individual buttons, you'll have to calculate it yourself. Another alternative would be to use a collection view which will automatically layout the buttons (cells).

Related

Collection View Compositional Layouts - Layout on the fly

After seeing the wonderful Advances in Collection View Layout Session, I wondered if is possible to use the capabilities implemented in the new Collection View Compositional Layouts framework to create a layout based on previously unknown cell sizes.
My problem:
Imagine a horizontal image gallery with two levels, the photos can be "vertical" or "horizontal", and the app is fetching them when are needed for display, and they are provided randomly ("horizontally" or "vertically"). So we have to populate the gallery with a "random pattern" (Pinterest style, here is how to do it with UICollectionViewFlowLayout).
I cannot see a "group" pattern to populate the cells, because the layout has infinite possibilities, vertical divisions can appear to create groups, but also can not.
Is it possible to archive with Collection View Compositional Layouts?
Thank you.
When you're setting your item layout size, you can use an estimated layout dimension to make the size dependent on its contents. So an image view can set the cell size from the inside out using constraints. You size the image when you populate the cell, depending on whether it is horizontal or vertical, and the image view adopts the size of the image and the cell adopts the size of the image view.
(If you needed even more control you could construct your group as a NSCollectionLayoutGroup.custom, which allows you set every item's frame manually. But there's no need for such extremes in this simple situation, and besides, that assumes you know the frame at layout declaration time, which you probably don't.)

Floating view into second row with autolayout

Can I setup constrains on storyboard view controller views so that I will have three views one next to other when there is enough horizontal space. In other case it will "float" one of views to next line?
Like on this example:
Enough space
Texts causing third view to "float"
Maybe stack views can help here?
There is no reason to expect the auto layout system to be able to accomplish this, nor can it.
What you want to use here is a collection view (UICollectionView) and have each of your views be a cell in the collection view. In fact, if you look at your views, they look quite the reusable views, where each one has an icon, a title and a detail text. A collection view can be set up to put cells one next to the other until there is no more space, after which cells are added below, and so on.
You can then setup your scene to layout around your collection view using auto layout, where other views would reposition correctly below the collection view content when the collection view grows in height.
See this layout as an example of what you need.
No. There is no way to setup views and constraints in a storyboard that automatically float into a new row if they don't fit into the same row.
(In my opinion that's a big weakness of the Autolayout system.)
The reason for that lies in the concept of constraints: Mathematically they represent linear equations that are normally independent for the x and y dimension. The only exception are aspect ratio constraints that connect the width of a view with the height of that (or another) view. But I cannot think of a way how you could use an aspect ratio constraint to break views into a new line if needed.
When the system resolves your constraints at run-time and computes the actual frames of your views it simply solves the system of linear equations for each dimension (or for both dimensions if an aspect ratio constraint is present). Adding the option of floating views to the Autolayout system would make the whole layout process a hell of a lot more complicated because you cannot describe that behavior as a simple linear equation.
(Stack views won't help as they only work for one dimension as well: either x or y.)
Recently, I needed the very same floating behavior you described and created a FloatingContainerView subclass of UIView. I generalized it so you can use it for any kind of view and translated it into Swift.
You can now find it on GitHub:
https://github.com/mischa-hildebrand/FloatingContainerView

Layout changing when running the app

I've been trying for days to make one layout of my app to work well, and after days of learning and mistakes I still can't get the table cell layout to look how I want it to be.
This is how my cell .xib looks like in the editor:
http://i.stack.imgur.com/VEr3r.png
And this is how my app looks like when running with suggested constraints:
http://i.stack.imgur.com/wiK1f.png
Why is that? How I can find my mistake and make the layout like it supposed to be, in the view?
Suggested constraints are rarely what I actually wanted to see.
For each label with fixed text, lock the horizontal and vertical positions either to the view or to the next adjacent item.
For imageViews, choose the size you want and lock the height and width.
For labels that you will be dynamically changing the text on, pick a size that will hold the longest string and lock the width. You'll need a vertical position constraint.
You have many options to simplify your layout.
you can use the stakview or create a static UITableView and insert your component inside the cells and enter the Constraint. excellent tutorial http://www.runtimecrash.com/2015/09/17/exploring-uistackview/

Fill UIScrollView with its content using autolayout in iOS

I am making a form based UIScrollView, which will contain some labels and text fields.
My ScrollView Height will increase as per the iOS device height.
PS: I do not want to add constraint to each and every element of the Scrollview, because in my case there could be 100 form fields.
What I want is, the inner content to fully occupy my scrollView like this:
Till now there a are no special constraints, the button is tagged with the bottom edge and the scroll view is pinned from the top edge. Also, the vertical spacing between scrollview and button is defined.
This is the autolayout constraint screenshot.
If the number of labels is variable, I recommend doing them in code, rather than in Interface Builder.
In code, you can use a loop to set every label to have the same width/height as the one above it. You may want to set their height to be >= a minimum value. Be sure to anchor the first label with the top, and the last label with the bottom.
But this can be cumbersome, why not just use a UITableView? you may modify the row height to let the cell fully occupy the view.
- tableView:heightForRowAtIndexPath:
- tableView:estimatedHeightForRowAtIndexPath:
I just face the same issue and already write a pod called TLFormView that do exactly that: a form based on UIScrollView.
It also has some nice features like:
declarative form taxonomy with TLFormModel Just extend it, add the properties you want and that's it. No delegate, no event handling, no boilerplate.
a nice way to handle different layouts for iPhone and iPad
conditional visibility with an NSPredicate that can access all the values in the other fields (e.g: show field A when field B has certain value)
in place help with a popover
all the fields are TLFormFields that extend UIView so you can place whatever you need.
You can try it right from the command line with pod try TLFormView.
If you want to know more I wrote some blog post about it here.
Please let me know your thoughts about it here or as a comment in the blog posts. Also any contribution is extremely welcome in the GitHub repo

How to make a fluid layout in iOS?

What is the proper way to make a fluid layout in iOS, in the sense that hidden elements do not take up space anymore?
I have a table view with in each cell a customized detail-type of view with title, subtitle and a row with some extra information:
The extra information can be up to three pairs of an icon and a label with a value. The layout of all views inside the cell is done using AutoLayout with no missing or ambiguous constraints.
What I would like to achieve is that when the value is 0, the icon and the label are not displayed and the views on the right are shifted to the left.
If I just use the setHidden: method, the width of the hidden parts are not changed, so that there is just whitespace, but no views are moved. Example:
It should look like this:
The following questions are related but do not seem to fit my case:
Fluid UI layout on iPhone
AutoLayout with hidden UIViews?
I have tried to follow the approach with creating layout constraints for the four frames that need to be set to zero: the width of the heart-shaped icon, the width of the label containing the value, the whitespace in between those and the whitespace between the label and the next icon. This did not work because I could not bind the layout constraints to the outlet in the code, and besides it seems a cumbersome method for something that should be a common scenario.
EDIT: I fixed the problem with the outlets to constraints: to do this it is necessary to create a subclass for the table cell and creating outlets for the constraints there.
With "common scenario" I refer to doing something similar in web design, where setting the display style to none is simple and has the desired effect. I expect that there is something similarly simple for this in iOS.
I have been thinking of using a collection view with reusable cells, but then I need to set up a delegate and a datasource and everything, and before I would go this way I wanted to make sure that that is the way to do it.
There is no need to remove a hidden view. Connect the constraint to an outlet in the code, and when you determine a view is hidden, subtract from the constraint's constant. Then, in the cell's prepareForReuse, remember to return the constraint's constant to the correct value.
Hidden views maintain their frame, so auto layout will have no reason to adjust the view. The correct way to do this would be to remove the views from the superview. The last thing you must do is double check the constraints. Since you will be removing views, you cannot use those views for auto layout. This will require quite a bit of constraint setting on your UI.

Resources