UICollectionViewFlowLayout with items of different size - ios

I have an UICollectionView where the items can modify at run time it's height.
The problem is that when an item is higher than another, the item are surrounded by a lot o blank space.
I'm looking for a property that create this:
and I want use UICollectionView not github example or third part implementation.
Thanks.

I don't believe UICollectionViewFlowLayout behaves this way. Try to reload your collection view after modifying the height or returning a different value for that cell in collectionView:layout:sizeForItemAtIndexPath: and see if the gap fills. Otherwise, I'd recommend using a custom UICollectionViewLayout subclass.
This class might fit this purpose properly - a UICollectionViewLayout subclass to work with your collection view:
https://github.com/aceisScope/WaterflowView/blob/master/WaterFlowDisplay/WaterFlowLayout.h

Related

How can I make a carousel like this?

How can I make a carousel like this with UICollection view?
A UICollectionView has a collectionViewLayout which is of type UICollectionViewLayout. It is this layout object which is responsible for how the cells in a collection view are laid out.
If you want a layout object capable of stacking the cells on top of each other as in the image you've posted you can either build your own UICollectionViewLayout or use a layout which somebody has already created and made available. Examples are:
https://github.com/gleue/TGLStackedViewController
or
https://github.com/victor-pavlychko/DeckCollectionViewLayout

Is there a "self.tableView.estimatedRowHeight"like method for collection cells?

I'm trying to make self resizing cells for my collection view. Ill display text parts and those text parts have many sizes, since every cell will have a paragraph. Reading a guide on appcoda and useyourloaf i got the solution to make it with table view, so the only thing i can't do on the collection view cell is this
self.tableView.estimatedRowHeight
for obvious reasons I can't use it on collection view. Is there any similar thing that I can do for collectionView cells?
PS: I can't change the collection for a tableView.
PS2: I'm using swift
In theory there is; Apple has been claiming since WWDC 2014 that there are self-sizing collection view cells in exactly the same way as for self-sizing table view cells.
But in fact every time I try this feature, my app crashes. So in my view the answer is: no, if you want dynamically sized collection view cells you will have to size them dynamically yourself. This is not difficult, however. Just implement collectionView:layout:sizeForItemAtIndexPath: and set the size of the item. If you want it to be based on internal constraints, call systemLayoutSizeFittingSize: here.

Getting Columns in UICollectionView

How can I add column headers on top of my uicollectionview for each column?
I've been trying all sorts of things for days and had horrible luck :(
I'm just using a regular uicollectionview and have 20 or so items in it.
I don't need the header to stay floating or anything sophisticated, just need a single label of text above the first row in each column.
Any ideas?
I'm assuming you're using UICollectionViewFlowLayout. You need to set the headerReferenceSize property to something higher than (0, 0). (Or you can implement collectionView:layout:referenceSizeForHeaderInSection: if the header sizes differ.)
Then just provide your header view in collectionView:viewForSupplementaryElementOfKind:atIndexPath:. Your view should be a UICollectionReusableView. These work similarly to cells in terms of reusability.
What has worked for me is to create a UIScrollView above the UICollectionView.Add UILabels for each column in the UIScrollView and keep the scrolling synchronized via the UIScrollViewDelegate method:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
Both the UIScrollView and UICollectionView will take a UIScrollViewDelegate delegate object.

What's the best way to build a very flexible/dynamic "header" in UICollectionView

I need to build a UICollectionView with a UICollectionViewFlowLayout and a very dynamic "header" (for clarity, I'll call it "view A" to avoid mixing it with a true collection view header) but I'm not sure about what can be the best way to do that: collectionViewCell, header or supplementary view?
What I mean by flexible, the bullet point being ordered by decreasing importance:
View A will contain buttons and subviews that need to detect gestures so I must be able to detect actions on subviews of view A.
I need to be able to reload data on the collection view without reloading view A.
I need to be able to update the layout of subviews of view A whenever I want (on viewDidScroll of the collection view delegate for example, update according to contentOffset changes).
If possible, I'd like to be able to change the frame of view A dynamically (I mean without having to invalidate the layout). I would like view A to be sticky at the top and shrink while scrolling until it disappear. Have a look at recently launched "Secret" app to see what I mean (done on UITableView for them). Though I could just scroll without changing the frame and cheat by changing the layout of subviews (see point 3) in order to give the sensation of a sticky header.
What do you think is the best component to do that? Can I use a UICollectionViewCell, a header or a supplementary view? If so which one? If not, do you think of an alternative way I could use to have the same behavior (transparent header and view A behind the collection view? adding view A somewhere else, where, in the view hierarchy?).
Thanks for your help!
Take a look at the UICollectionReusableView class.
You can register your nib on the CollectionView as "SupplementaryView" (registerNib:forSupplementaryViewOfKind:withReuseIdentifier:, use the UICollectionElementKindSectionHeader kind of view)
then you have to implement the collectionView:viewForSupplementaryElementOfKind:atIndexPath: method in your delegate and make sure to return something for the UICollectionElementKindSectionHeader kind.
and finally you have to implement the collectionView:layout:referenceSizeForHeaderInSection: method of your UICollectionViewDelegateFlowLayout to set the size of your header.
Let me know if it help.

Custom UITableViewCell's subviews using auto layout - no xibs, all in code

Custom UITableViewCell's subviews added in code using auto layout works (verified). However the whole point of doing this was to not have to calculate the height of each tableview cell and the delegate method heightForRowAtIndexPath expects a height while drawing the tableview.
How can I figure out this height based on content using the auto-layout (visual format language based addition in code already added and working) and return it to this heightForRowAtIndexPath?
Also I'm I can't really do this on a background thread (or can I?) and therefore if I have a UITableView using this backed by a list of say 1000 records, this will take forever, is that right?
Autolayout in this case just means that you don't need to calculate the frame sizes of your subviews within each cell. It's got nothing to do with the heightForRowAtIndexPath method - this is used by the table view to define the cell's frame, which will then inform the layout of the subviews.
Using Autolayout to determine the heights would likely be pretty slow, and you can't do it on a background thread. If you have 1000 rows then I'd consider a hierarchical structure instead of a single table as that will be pretty tedious to scroll through. You could also consider calculating the heights at the point of setting or creating the data.
You may be able to set up an offscreen view using your constraints, populate it with your data for each item, then record and cache the height. However you'd have to do this at the data end rather than in the height method, as it would be far too slow.

Resources