Modifying a UICollectionViewFlowLayout to change cells positions - ios

I need to slightly change the way FlowLayout draws cells.
I need to set the collection to scroll horizontally and I want to draw cells from left to right, moving to the next line when the width is completely filled and taking into account pagination.
Here some images to clarify my question:
This is the current behaviour of the FlowLayout:
this is what I'd like to obtain:
Some notes:
I need paginationEnabled = YES
I want to fix the rows to a maximum of 2
I have a fixed number of cells too.
Is there a way to achieve this behaviour working with a UICollectionFlowLayout? Or is this the case to create a totally custom UICollectionLayout?

I believe you would have to manually fill the cells checking the indexpath.row and also checking the width of each cell and self.view.frame.size.width

Related

Set dynamic subviews positions in UITableViewCell

I am trying to implement the below views variations:
3.
So as you see in the first image we have price or pts and popular, in the second image we have popular and not available, and the last image we have them all, and whenever an option is no there the other option will replace its position.
It is hard to update constraints for each case and what if later we have more options
Any ideas or suggestion thanks.
First enable tableview dynamic row height. then set all the views in cell to top.Set the second row dynamic labels bottom anchor to cell bottom anchor using lessOrEqualTo.This configuration will adjust your cell height automatically.You don’t need to calculate it.

Is it possible to use self sizing cells within self sizing cells?

I want to have self sizing cells within a tableview with self sizing cells. But on first initialisation some cells are not correct. After a scroll to the bottom and the cells will display again the cell size is correct. In the screenshot you can see that the top 2 cells have a white space at the bottom and the third one doesn't. They should all look like the third one.
This is the issue in my main project.
Screenshot
The problem with automatically sizing cells inside automatically sized cells is a bit tricky because you have to understand how it works. UITableView works with estimates most of the time. It usually does not calculate the contentSize precisely because to calculate it precisely, it has to first instantiate every cell, layout it and then calculate its size.
The precise values are calculated only for cells that are displayed (visible in current scroll frame).
The tricky part is that the inner cells (inside your outer cell) are not displayed until the outer cell is displayed therefore the outer cell does not have size calculated correctly. Also note that UITableView does not automatically update cell heights unless explicitly said to do so.
The solution, if you really have to do this, is to calculate the height of the outer cell correctly before it is displayed and manually set a height constraint.
If you know the height (from data source), it's easy. If you actually need to calculate the height of the inner table, you can do something like this:
// make the table high enough to display all cells
innerTableHeightConstraint.constant = 2000
// reload table
innerTable.reloadData()
// force layout
innerTable.layoutIfNeeded()
// now the contentSize is correctly calculated
innerTableHeightConstraint.constant = innerTable.contentSize.height
The whole concept is tricky and ideally you should prefer using UICollectionView or table sections. When you are using inner table views, there won't be any cell reuse for the inner tables and your performance will suffer.
You should not wrap UITableView into UITableViewCell, try to use UITableView Sections instead to add an extra depth level to your UITableView.

Attach/Stick a UIButton under the UITableView

This illustration shows what i'm trying to do:
The green list is the UITableView where it dynamically adjust it's height based on the number of items inside of it.
Underneath of the UITableView is a button that should follow the UITableView whenever it changes it's height size.
The UIButton should always be beneath the UITableView whatever the size of the UItableView.
I'm currently using autoresizing for UITableView
I have tried to use Autolayout but it seems i can't still find the answer.
i currently have no constraints in the layout.
This boils down to calculating the height of the table view that perfectly fits the cells. Basically you need to measure the size of every cell, then create a height constraint on the table view, and set its constant to the sum of the cells' heights.
Measuring the height of cells is tricky thought. If you only have a few cells (like in your illustrations), you can just instantiate all of them, keep them in an array and use systemLayoutSizeFittingSize to calculate their sizes. If you use multi-line labels, it is also important to set their preferredMaxLayoutWidth to appropriate values.
However, if you have only a few cells (and so cell reuse is not important), stack view is probably a better choice than table view. It's just too tricky to calculate the perfect height of a table view.

In tableview i have 4 static cells. How do i make row height automatically calculated to fit the label inside and one manually

So i have four sections and one cell in each one of the sections in my static tableview. One of them is displaying a picture and for that one i manually calculate the ration and multiply it by the width and that way i get the correct height. I do that using the "heightForRowAtIndexPath".
I also have three other cells and each one has a label in it. The labels content is different each time since i'm segueing to it from a different cell so sometimes the cell should be big enough for 1 row of text and sometimes for more. How do i calculate/set that to happen automatically?
Also in my storyboard i have the constrains for the label set to be 8 point away from the right left and top, thats all the constrains that are on the label. I already tried setting the tableView.rowHeight to UITableViewAutomaticDimensions but that doesn't do anything. The rows just stay at the same height as they were set in the "heightForRowAtIndexPath" or the same as in the storyboard if that function is not implemented. Been trying to solve that for probably more then an hour now and still cant figure it out. Thanks for the help. Also i'm doing all of this in swift.
If you implement heightForRowAtIndexPath it will also override any value for the table view's rowHeight. So, in heightForRowAtIndexPath return UITableViewAutomaticDimension, and do the same in estimatedHeightForRowAtIndexPath too.
As long as your cell has a solid Auto Layout configuration, that's all it takes to make auto-sizing cells work.

Scrolling to next cell in UICollectionView

I have a UICollectionView in a container View. It is sized in such a way that I see only one cell at a time. I have disabled vertical scrolling so only horizontal scrolling takes place.
Everything works just peachy where I scroll horizontally across cells. The disadvantage of this scrolling is I can scroll and get to a position where I see half portion of two cells with a gap in between.
What I want to achieve is to show only one cell at a time and never show two half cells. So the scrolling should take me to the next cell one at a time.
Hope this makes sense.
Please let me know if anyone has tried or can help me to achieve the same. Thanks.
You can scroll one cell at a time by setting pagingEnabled = YES. Or for regular scrolling, you can adjust where the deceleration ends by overriding targetContentOffsetForProposedContentOffset:withScrollingVelocity: of UICollectionViewLayout. When using the later method, you would typically do the following:
Determine the nearest index path to proposedContentOffset. If there are no gaps between your cells, you can use [UICollectionView indexPathForItemAtPoint:]. Otherwise, you may have to inspect your layout in some way to determine which index path you want to scroll to.
Determine the frame of the index path you want to scroll to by getting the layout attributes for that index path
Determine the content offset that will position the given frame where you want it.
Make sure your padding between cells is set to zero as well. Paging enabled will stop on multiples of the view bounds.
// Set up flow layout
var flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout();
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: flowLayout)
collectionView!.pagingEnabled = true
Check out my answer over here: ScrollView or CollectionView?
It sounds like you have paging enable but the page size doesn't match you cell size plus the insets left and right of the cell.
Swift 5:
collectionView.isPagingEnabled = true

Resources