1

So I have self sizing custom UICollectionViewCells, which are self sizing.

Now I need that UICollectionView wraps it's content, without exact predefined size. Like android linearLayout wraps it's content, or any of WPF panels.

How can I achieve that?

The thing is I want the UICollectionView measured by itself and wrap it's content. I'm going to create it in code and add as child to another view from code.

I'm using flowLayout.

Any suggestions?

EDIT: Attached sample project which contains only custom collection view https://monosnap.com/file/9Y78XqcwAUNFxCo382u3bTr7CDS77F

nrudnyk
  • 692
  • 5
  • 21
  • 1
    It's unclear what you mean by "wraps its content." Flow Layout will, by default, "wrap its content." If you have 12 cells, and 3 will fit on the width of the view, it will wrap the cells so you have 4 rows of 3 cells each. If 6 cells will fit, it will wrap so you have 2 rows of 6 cells each. If that's not what you are asking, then please clarify your question (and *"like android linearLayout"* really means nothing in this context). – DonMag Apr 27 '18 at 19:39
  • Oh, you mean like the collectionview only takes up as much space as the content requires? (I know a little bit about android development) You can just give your view (in which you want to embed the collectionview) a constraint based layout so it aligns exactly how you want it, and then just make the uicollectionview fill up that view, if the content height exceeds the collectionview height, scrolling will be enabled. Android and iOS work entirely different, you need to think and work different for each one (in my experience) – JoniVR Apr 27 '18 at 21:46
  • I want it to have 1 item in a row, so it’s basically 1 column, and i want it to have width as the wider ktem in it. Also height takes as much space as the content requires. It is in constraint based layout, but since im adding it from code the constraints should be added as well from code? And which ones!? – nrudnyk Apr 28 '18 at 07:31
  • @JoniVR any suggestions how to achieve behavior I explained in previous post? – nrudnyk May 14 '18 at 08:23
  • @nrudnyk I'm sorry, I didn't see it before. I'm not entirely sure what you're trying to achieve. If you want to customize the itemsize, you should implement `UICollectionViewDelegateFlowLayout` with the `sizeForItemAt` function. If you want just one column then make sure you set the amount of sections to 1. I do recommend reading the Apple [documentation](https://developer.apple.com/documentation/uikit/uicollectionview) on `UICollectionView` – JoniVR May 14 '18 at 08:44
  • @JoniVR I've read that documentation. And I know that I can use delegate with `sizeForItem`, but items will be labels, so they will have intrinsic size, based on which cells could be measured. – nrudnyk May 14 '18 at 09:46
  • @JoniVR What I want to achieve as an end result is that UICollectionView has 1 column, in which items will be measured by themselves, and that collectionView should calculate it's size automatically. I suspect I should use some special constraints to the collectionView, but I couldn't find any proper example over the internet... – nrudnyk May 14 '18 at 09:48
  • @nrudnyk and should there only be one item visible at a time or not? – JoniVR May 14 '18 at 09:54
  • @JoniVR one in a row, but multiple rows. – nrudnyk May 14 '18 at 09:55
  • @nrudnyk do you want them to be paged or not? (Sorry for all these questions but I need to understand your specific issue before I can try to help) – JoniVR May 14 '18 at 09:56
  • @JoniVR no, like a list, and when it reaches bottom of it's edges (which grows until reaches edge of parent container) starts to scroll – nrudnyk May 14 '18 at 09:57
  • did you check out this question? https://stackoverflow.com/questions/25895311/uicollectionview-self-sizing-cells-with-auto-layout?rq=1 – JoniVR May 14 '18 at 10:16
  • indeed, and cells measured itself fine, but I don't know how to force UICOllectionView to measure itself (wrap cells). So if I set width\height it's fine, if no - size is 0 – nrudnyk May 14 '18 at 10:20
  • forgot to add @JoniVR in previous comment – nrudnyk May 14 '18 at 12:34
  • @nrudnyk so you want the collectionview to adjust it's own size when there's no content or dynamically adjust it's size based on cell height (like Android does with the wrap property)? – JoniVR May 14 '18 at 12:38
  • @JoniVR exactly. I want it to has width as it's widest item and height depend on items count... (yes as Android wrap_content) – nrudnyk May 14 '18 at 12:42
  • @nrudnyk hmm I'm not sure if there's an easy way to achieve that behavior without some code trickery.. may I ask why you'd want to do that though? Can't the collectionview size just be fixed and the cells dynamic? I get that that's probably what you're used to from Android, but in my experience, you really shouldn't try to fight the difference between the different Dev api's from the platforms. Maybe [this](https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/ViewswithIntrinsicContentSize.html) has some more info on it.. I'm not sure. – JoniVR May 14 '18 at 12:47
  • @nrudnyk perhaps something like this: https://gist.github.com/houxg/796d3ebd32403a4b23b2a568bd47e41e – JoniVR May 14 '18 at 12:52
  • @JoniVR sorry, I've missed this yesterday. I need to display a list of items in my custom control underneath, that'w why collection view can't be full screen size. And I don't want to add it from ib, since it will be shown by custom control, so I can't hard code sizes. It would something similar to legend. I've created sample which contains only custom collection view, and attached it to OP. Maybe you will have ideas on how to achieve desired behavior. – nrudnyk May 15 '18 at 06:27
  • Hi @nrudnyk, I have some questions before starting to implement what you want. 1-If you want to have one in a row, but multiple rows, why don't you use `UITableView`?. 2-If you want have more than one in a row, how many item a row you want. 3-Is there any case when CollectionView content size is alway bigger than screen? . 4. What are maximum height and width of CollectionView? – trungduc May 15 '18 at 16:50
  • @trungduc 1. because I what to have 2 options - horizontal and vertical later on. 2. only one. 3. If there will be super long label. rare case but it's possible. so ui collection view will became size of it's parent and it's content size will grow. 4. as it's superview – nrudnyk May 15 '18 at 17:24
  • @nrudnyk Check this out: https://stackoverflow.com/a/42438709/6863743 Is this the behaviour you're after? – JoniVR May 16 '18 at 20:06
  • @JoniVR something line that, but I won't add that from storyboard\xib and I've already tried it in example I shared. Doesn't work ... – nrudnyk May 17 '18 at 13:32
  • Duplicate?: https://stackoverflow.com/questions/20792299/uicollectionview-autosize-height – Anton Belousov May 19 '18 at 23:20
  • @nrudnyk if you don't want to use the storyboard, you can do the same thing programmatically. – Pipiks May 22 '18 at 07:30

3 Answers3

0

Can you check the size of bounds of the collectionView and update the height of the container accordingly. You might need to override some api's to update this.

Ansh
  • 53
  • 7
0

You should try to set the estimatedItemSize of your collection view flow layout :

if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    flowLayout.estimatedItemSize = CGSize(width: 1, height: 1)
}

Source : https://medium.com/@wasinwiwongsak/uicollectionview-with-autosizing-cell-using-autolayout-in-ios-9-10-84ab5cdf35a2

Pipiks
  • 1,893
  • 10
  • 27
  • I did use that for autosizing cells, but i need ‘UICollectionView’ to wrap my content. You might want to look at the posted code before answering. – nrudnyk May 21 '18 at 15:13
0

You should try setting content Hugging Priority and content Compression resistance priority for the collectionView and also its subviews if needed.

This can be achieved by size inspector in storyboard/xib but as you are using code putting the code to achieve the same.

// Hugging priority is given so that views are sized less than the estimated size.
collectionView.setContentHuggingPriority(1000, for: .vertical)
collectionView.setContentHuggingPriority(1000, for: .horizontal)

// Content Compression resistance is given so that views are not sized less than its size because of other constraints.   
collectionView.setContentCompressionResistancePriority(1000, for: .vertical)
collectionView.setContentCompressionResistancePriority(1000, for: .horizontal)

you may need to set the same for the subviews of the collectionView if they are need to be hugged according to their size. For example, let's take you have label in your collectionView whose size will vary, you may need to set the content hugging and resistance priority for label too.

Karthick Ramesh
  • 1,361
  • 16
  • 25