> On Aug 10, 2016, at 11:10 AM, Doug Hill <cocoa...@breaqz.com> wrote:
> 
> I'm currently trying to implement something that seems basic but has been 
> driving me nuts: making a Collection View with cells that are dynamic-width 
> and height at runtime.
> 
> I was able to accomplish this with Table Views by using the dynamic height 
> constant. Following Apple documentation, I set the width of the table view 
> cell in IB to be an arbitrary size, for example using the default 600 pixels. 
> I then use autolayout to make the size/position of the table view subviews 
> adjust to the size of the cell. At runtime, the table view sets the width of 
> the cell, and autolayout can change the height based on the content (e.g. 
> multi-line labels.)
> 
> Now I want to do this using a Collection View. Reading Apple's documentation 
> and watching the relevant WWDC video, it looks like this will be just as 
> easy, right? As is my experience working with Collections, nothing ever comes 
> easy.
> 
> OK, so I do basically the same thing as I was doing with tables.
> 
> • Create a Collection View Controller in a Storyboard.
> • Create a collection view cell in the collection view inside the Storyboard.
> • Make the cell the width of the collection view.
> • Add some labels that fit the width of the cell using autolayout and allow 
> for multiple lines (e.g. dynamic height)
> • Use the default flow layout in IB and set the item size in the flow layout 
> to be something less than the size of the collection view.
> • Make sure section insets are 0.
> • At runtime during viewDidLoad for the collection view controller, set the 
> item size and estimated item size in the flow layout to be something related 
> to the size of collection
> 
> I run this and behold…it crashes. And there are lots of warnings:
> 
> "The behavior of the UICollectionViewFlowLayout is not defined because: the 
> item width must be less than the width of the UICollectionView minus the 
> section insets left and right values, minus the content insets left and right 
> values."
> 
> This is kind of odd since I go through a lot of trouble to make sure the cell 
> item size is not too big. Here is what I see for the item size: Yet the app 
> still crashes due to a cell that is too wide for the collection.
> 
> So, somewhere else the item size is getting set behind my back to something 
> other than what I set in itemSize, estimatedItemSize, cell bounds, etc.
> 
> Before I go any further, I wanted to see if there's an official way to 
> accomplish my goals without doing way more work, that is having to subclass 
> the flow layout class. Should the default flow layout class even be able to 
> do this? I see a lot of different ideas on the interwebs that involve doing 
> things with the flow layout but I'm hesitant to go down that path. Shouldn't 
> this very basic use case be doable without having to get into the complexity 
> of the layout class? Honestly, the documentation for this is terrible. 
> There's a lot of hand-waving and assumptions that don't quite spell out most 
> of the details of this use case.
> 
> Thanks.
> 
> Doug Hill

Digging into this a little deeper, I find this tidbit in Apple documentation

=============

UICollectionViewFlowLayout: estimatedItemSize

The default value of this property is CGSizeZero. Setting it to any other value 
causes the collection view to query each cell for its actual size using the 
cell’s preferredLayoutAttributesFittingAttributes: method

=============

OK, this makes sense why my cells all ended up with the wrong size. The cell 
class needs to override this method to set the cell's size instead of all the 
other ways I used above.

Remember, my objective is to make the cell width be the same width as the 
collection view itself. Huh, collection cells don't have a reference to the 
collection view it's contained in. Given that I don't know how wide the 
collection view is, I'll pick an arbitrarily small width so at least the app 
won't crash. Let's say 300 pixels. I call the cell's super implementation of 
preferredLayoutAttributesFittingAttributes and then change the frame property 
of the layout attributes it returns.

Progress! The app no longer crashes right away and the collection cells now 
have my adjusted width. I do see a couple of problems though:

1) The height of the cell is wrong
It seems to use the default height of the cell as it is layed out in the 
Storyboard, not the new height of the cell based on my autolayout constraints. 
This is pretty much the entire reason I'm using the estimatedItemSize property 
in the first place; it's supposed to figure this out for itself. Ugh.

As a workaround, I can calculate what the height should be based on the origin 
and height of the multi-line label, and change the layout attributes' frame 
property to use this.

2) The app still crashes
When scrolling, it will show some number of cells correctly, then I'll see one 
that has an incorrect width and the app crashes. The crash happens inside the 
call to the cell's super implementation of 
preferredLayoutAttributesFittingAttributes, and happens whether I update the 
height as in #1 above.

OK, so now there is some unsafely when updating the layout attributes returned 
by calling super's preferredLayoutAttributesFittingAttributes. Digging around 
in the Apple docs I don't see any mention of anything about how this might be 
unsafe.

Again, looking for any ideas, pointers, etc. about any of this, including 
whether I'm going about this the wrong way.

Doug Hill
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to