Display one row in UICollectionView - Swift - ios

I'm trying to figure out how to limit a UICollectionView to display a horizontal scrollable list in a single row.
Any Ideas?

I just used something that is working for me:
Set the Scroll direction to Horizontal.
Set the size of your Cells using sizeForItemAt indexPath method.
Set a constraint to your CollectionView making its height equal to (or a bit greater than) the Cell's height which you specified above.
The logic behind it:
When the height of CollectionView is equal to the height of it's items and it is set to horizontal scroll, then it can only show them in one row. I said "or a bit greater than cell's height" because if you set the height of your CollectionView twice bigger than cell's height then it can fit 2 rows of cells and it will show them in 2 rows instead of one.

Related

How to automatically adjust height based on label content inside collection view cell in swift?

I want to achieve a self resizing height collection view cell (image above) using swift. I have tried many options like UICollectionViewDelegateFlowLayout and sizeforItem. Nothing works for me. I want to achieve similar result like in the image
Set Estimate size to automatic and do not implement sizeForItemAt , In CollectionView Cell, for each label give number of lines to zero. It will resize automatically.
Set Min spacing and line Spacing to zero as well
Also, In the collection View cell, three labels should be in stackView with fill alignment and distribution , set multiplier to center label width as 0.6 ( or whatever you want ) of total cell width. Give equal width constraint to first and last label like this image :

How to make UICollectionViewCells with content lined up across cells

I have a UICollectionView that is using flow layout and it is horizontally scrolling. In each cell, I have five subviews (labels and image views). I have an array of model objects, one object per cell, that contains the data to be displayed in each subview in each cell.
Some items can have more content than others (some labels will have more text), but I want all the cells to be the same height. I also want it so that the top of each subview is lined up with the tops of the same subview in the other cells. And if all model objects have a nil value for one of the fields, then the subviews for that field should be left out of each cell.
For example, I have the following image where it shows three cells and the subviews in each cell. For this example, all of the cells have data for subview 1, so it shows up in all of them. But only the first two cells have data for subview 2, so it only shows up in those cell. Likewise, subview 3 only shows up in the first cell because that is the only cell that has data for that subview. Now for subview 4, none of the cells have data for it, so it is completely skipped and there is no space taken up in any cell to render it. Instead, subview 5 is rendered in the place where subview 4 would normally have been rendered and it is only in the third cell because only that cell had data for it.
I also have dashed lines between the subviews showing that they are supposed to be lined up across cells.
Question
So I am just curious what the best way to do something like this is, given these requirements. Could this be done with AutoLayout or do I need to manually layout these subviews?
The only way I can think of doing this currently is to iterate through all of the model objects, try to figure out how tall each subview is and essentially keep track of the tallest height for each subview. And if no cell has data for a particular subview, the height of that one would be zero.
Next, I would turn those heights into computed offsets for each subview, where the computed offset would be the sum of the heights of the subviews above it and the spacing between each subview.
Then, I would try to lay these out manually, I suppose, with the frame of each subview being set to some width (not sure how to calculate the optimal width of each subview) and a vertical position equal to the computed offset of that subview. Or I guess I could do AutoLayout as well where the top constraint on a field is equal to the computed offset for each subview, but is that less efficient?
And then I guess the height of each cell would be just the computed offset of the last item plus its height plus the spacing to the bottom of the cell. So then I would take the max height of all the cells and set all of the cells to the same height.
But I was just curious if there was a better way of doing this or if there was anything that I was overlooking that could simplify things. I would also like this to be as efficient as possible as the collection view could have up to 100 items in it.
You will need to loop through your data, calculating the "max height" for each item.
I'd suggest putting your 5 "views" in a vertical stack view.
As you loop through your data, get the max height for each of the 5 views. Then, when you set your data in each cell, set the height constraint on each of the 5 views (or, set a view hidden if it is nil in all data items).
Then set your collection view's height to the necessary height to fit all the views plus spacing.

Dynamically size both UICollectionViewCell and UICollectionView, maybe UITableViewCell

I'm building something as shown in the image below:
I'll try to explain a bit more what my goal is. I have a UITableView. One UITableViewCell (1) in here will contain a title (left out in this image) and a UICollectionView (2) (same width as tableview/screen). This collectionview uses a subclass of UICollectionViewLayout to make it horizontally scrollable, evenly spacing the items.
Each UICollectionViewCell (3) in here contain a title and description, both with dynamic heights. Also, this cell contains a new collectionview (4). This new collectionview contains a number of items (5). In this most inner collectionview a row can contain a maximum of 5 items.
Currently I have a tableviewcell (1) with horizontally scrollable collectionview (2), putting the items (3) next to each other. I also have the most inner collectionview (4) putting the items (5) in the correct way.
The difficulty I'm facing now is:
To dynamically size the height of collectionview (4), depending on how many rows for the items are needed, so depending on the number of items.
To dynamically size the height of collectionviewcell (3), depending on the height of the title, description and collectionview (4).
If possible, to dynamically size the height of the collectionview (2) and the tableviewcell (1) containing this, as high as the biggest cell (3).
I hope someone would have an idea how to do this, if it is even possible. I do hope so, while keeping the code 'easy' to follow.
I can do a lot with constraints / autolayout, but this I can't get my head around.

UITableView content size not getting proper

I have UITableView for display for chat message list. I am using 5 type of different with dynamic height. Minimum cell height from 20 to maxHeight( approx 1000 px). UITable view cell dynamic height is set by "self.messageTableView.rowHeight = UITableViewAutomaticDimension".
What Should be common estimate row height.
After reload UITableView content size not getting properly. If user scroll then content size increased.
It is not enough to just set rowHeight to automatic dimension. You also need to install proper constraints for cell subviews so the cell can calculate its height based on that constraints.
To use UITableViewAutomaticDimension for dynamic height calculation, ensure
1 - Leading, Trailing, Top and Bottom constraints to cell are added correctly and not creating any conflicts
2 - Add cell.layoutIfNeeded() in cellForRowAt method of UITableViewDelegate
3 - You can give any height as estimatedRowHeight, 44 is the default value, but you can give 20(your minimum) as well.

Have UITableViewCell resize itself with autolayout

I have 3 labels in a UITableViewCell and have the labels set so they will wordwrap. If they word wrap the text goes into the next cell. How do I get AutoLayout to expand the cell based on the content without having to write code in the heightForRowAtIndex method? Isn't there a constraint I can use to automatically adjust the cell based on the contentView?
The cell looks fine if the text doesn't wrap in the label. Once it wraps that is when the problem occurs and I would like to have the cell resize to fit the content and have the same spacing between the bottom label and the bottom as there is between the top and top label.
Unfortunately no, you can't do this. A table view calculates its own total height first and has a fixed idea of the size of each cell as they load, it won't determine it's height from the outside in and it won't let layout constraints change the height of a cell.
If you think about how tables work, with cell reuse, then you couldn't really size the table from its cells without loading in every cell and adding it to the scrollview, and performing a layout pass on the whole thing. That would probably lead to quite poor performance.
You could experiment with populating a "free" cell (i.e a cell you've just instantiated, not added to a table) and laying it out for each row in your datasource when calculating heightForRow.
As you are loading the individual cells, after you fill the labels, but before you load the instance of the cell, check the label height.
Something like:
cell.frame.size.height
If the height is large enough that you know the label has wrapped to two lines, then increase the height of the cell you are about to load.

Resources