Calculating sizeForItemAtIndexPath in UICollectionView without using the cells - ios

I am in a loop with myself on from where to get the cell's size in a collection view in case I have a cell with auto layout
I understand that sizeForItemAtIndexPath should get the size from the data and not from the cell itself, because the cell is not drawn yet, but in auto layout I can't calculate this just by looking at the data, unless I put in code the contraints in a way that I can later calculate from them (seems crooked)
On the other hand, UIView does have intrinsicContentSize and systemLayoutSizeFittingSize which gives the size of a view that's already drawn or going to be drawn.
But in sizeForItemAtIndexPath I don't have a view yet, and the data is just data.
the cell nib looks like this
In what way should I get the size of a custom cell (from .nib)?
I could technically hard code sizes for the images and icons, but that feels wrong. It also feels wrong to ask the view what size it is in a function that should tell the controller what size it is

You can use an off screen prototype cell which you configure and then use to determine its size.
This is a common approach for UITableView pre iOS8 to determine cell height. The same approach should work for UICollectionView.
See the accepted answer here: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights

Related

UICollectionView self-sizing-cell on iOS 8 will crash with UIDynamic flowLayout and repeating call to _updateVisibleCellsNow

I am trying to use the so called "self sizing cell" which means:
set estimatedItemSize on flowLayout
overide preferredLayoutAttributesFittingAttributes in cell class
Such as this: UICollectionView Self Sizing Cells with Auto Layout
And I need dynamic effect like this:http://www.teehanlax.com/blog/implementing-a-bouncy-uicollectionviewlayout-with-uikit-dynamics/
It works fine without UIDynamic, but I need UIDynamic. As what I see, it will call the prepareLayout and layoutAttributesForElementsInRect until die, there will be too many _updateVisibleCellsNow waiting in line.
I have no idea how to solve that, please help me in case u see. Or, if I am using those technologies in wrong way, please let me know.
Two things worked for me:
Make sure your collection view itself has layout constraints defined for placement within its superview.
I got this crash when the estimated size was larger than the final size. If I set the estimated size to a smaller value the crash stopped.
If any size or frame position changed, it will trigger all cells' preferredLayoutAttributesFittingAttributes until all cells' frames did not change.
The behavior flow is as the following:
1. Before self-sizing cell
2. Validated self-sizing cell again after other cells recalculated.
3. Did changed self-sizing cell
If second steps can't get stable all cells' position and size, it will become infinite loop.
Please reference my post here: UICollectionView Self Sizing Cells with Auto Layout

UITableViewCell size

I have a table view with cells in my IOS app. The thing is that when the cell loads I need to layout some stuff on it that is relative to the size of other elements. The problem is that I can't get the size because there is no viewWillAppear or viewDidLoad methods, which have actual bounds(with autolayout and constraints applied). What is the best way to work with cell's geometry and sizes in IOS, can somebody tell me ?
Auto Layout and self-sizing cells (in iOS 8).
The layout system will determine the size of the "stuff" in the cells, and proper constraints will then determine the cell's height.

Swift: UITableViewCell size to width of parent UITableView with autolayout enabled

I'm experimenting with autolayout and am running into trouble with UITableViewCell since they're created at runtime. My cells are loaded from a xib from the main ViewController. This xib has View mode set to Aspect Fill.
I've read about different ways to do this online and have yet to get any of them working. What's considered the best way to handle this?
It looks like your constraints aren't set properly, as the cell is shorter than the image's height.
Using AutoLayout and self-sizing cells is the easiest way to handle what you want to do. Once your constraints are setup properly for your custom cell, tableView:cellForRowAtIndexPath: can call dequeueReusableCellWithIdentifier:forIndexPath: and all the subview layout will be handled for you.
See the detailed walkthrough by smileyborg in his answer to Using Auto Layout in UITableView for dynamic cell layouts & variable row heights.
He also provides workarounds for the minor issue with the initial cell width being based on the storyboard cell, instead of the tableView width. I worked around it by setting the cell's initial width to the tableView's width, as Rasputin had suggested.

Calculate UICollectionView contentSize in tableView's heightForRowAtIndexPath

I have a collectionView inside a UITableViewCell. The collectionView's content is dynamic, hence, its height is dynamic too and the tableView cell's height depends on the collectionView's height. The collectionView cells have different sizes. The collectionView's height is always set to fit its contentSize height.
My problem is that the tableView's function heigthForRowAtIndexPath, is called before the collectionView is created (in cellForRowAtIndexPath) so, to return the height that fits the collectionView, I need to calculate it manually (which doesn't seem like a good idea for a collectionView with cells of different sizes).
I tried to use autolayout in order to use UITableViewAutomaticDimension but it didn't work (maybe I did it in a wrong way).
What is the best aproach to make a UITableViewCell consider the height of its subview in heightForRowAtIndexPath? Can I know a collectionView's estimated size without creating it?
Use self sizing, which is available in iOS 8. There are plenty of good tutorials online, like this one: http://www.appcoda.com/self-sizing-cells/.
The idea is that you can use auto layout and a few lines of code in viewDidLoad to render a table view cell that dynamically fits the content in it.
Some more tutorials:
http://useyourloaf.com/blog/2014/08/07/self-sizing-table-view-cells.html
https://github.com/smileyborg/TableViewCellWithAutoLayoutiOS8

Where to determine the height of a dynamically sized UICollectionViewCell?

I'm using UICollectionViewFlowLayout. My cells contain UILabels that differ in height (number of lines).
It seems that the best way to get the cell height would be in the subclass of UICollectionViewCell, because that is where I set the layout and have access to intrinsic size of my views, BUT:
collectionView: layout: sizeForItemAtIndexPath: is called before the collectionView: cellForItemAtIndexPath: delegate method, which means that I need to know the cell height before I have the actual layout of the cell.
Everything I came up with so far seems too complicated, like starting with fixed cell height, referencing actual height after labels in the cell load and reloading the data again with correct height. Is there a better way to do this?
Unfortunately, no.
For dynamically sized items in UICollectionView you need to know or compute the size of the cell before it is created. The traditional way to do this is to store the data for each row in an array and then compute the size of that data in collectionView:layout:sizeForItemAtIndexPath:.
For example, if you had an array of text to be displayed you could store the NSString objects in an array, measure that string in collectionView:layout:sizeForItemAtIndexPath: and return the size. UICollectionView then takes that size and calls initWithFrame: or setFrame: when configuring your cell's view.
It's also not a bad idea to cache these sizes if they don't change often.

Resources