Mixing self sizing cells with calculated sizes - ios

My initial task is to have equal widths of cells and make them fill the entire row of the collection view with UICollectionViewFlowLayout.
Is there a way to calculate height of cells using autolayout, but provide width from sizeForItemAtIndexPath?

In sizeForItemAtIndexPath, calculate the height using systemLayoutSizeFittingSize: with a CGSize of your desired width, and a height large enough to fit your largest content.
e.g. for cell width of 100 (large maximum height of 999):
[collectionViewCell.contentView systemLayoutSizeFittingSize:CGSizeMake(100, 999)];
Beware though, if you have multiline UILabel's, as you will need to fiddle with preferredMaxLayoutWidth. More details, albeit for a table view, here.

Related

Horizontal Collection View with different width cells

I have a UICollectionView where the width of the cells is dynamic based on text. When I set a spacing of 5px between all cells, this is the distance between the 2 longest cells but all the other ones are a lot more spaced.
I need the spacing to be always the same, even when the cells are very small or very big.
Any idea on how to achieve this?
So far I'm setting the minimumLineSpacingForSectionAt and the size of the cell is calculated based on the width of the text.

Content of Grid list to fill the height

I am placing content in the grid list component and I want the grid tile to grow accordingly to the content it has. I tried to use rowHeight="fit" as documentation states but it doesn't seems to work.
Here an example
MatGridList overall size is directly related to the rowHeight setting. The default rowHeight value is a ratio 1:1 (which means column width equals row height).
When you use a ratio, the list will have a fixed width/height ratio overall, so if the list can't grow in one direction because of window or layout restrictions, it can't grow in any direction. This is why your example looks the way it does. If you expand the width of the window, you'll see the list expand vertically as well. You can set a different rowHeight value to make the tiles taller than wide such as rowHeight="1:2" (that seems backwards to me but that's how it works).
When you use rowHeight="fit", this doesn't fit the list to the content, it fits the row heights to the list height, but as noted in the documentation, you must set a height on the list or a parent for this to work properly.
Setting a fixed value for rowHeight does what it sounds like.

Resize UICollectionViewCell to fit image

I'd like to resize UICollectionViewCell to fit image that is sensibly resized and maintains dimensions/aspect ratio. If I simply set the size of cell to size of image it may be way too big. Also, If I run on different sized devices, the spacing isn't consistent. Must I implement collectionView programmatically to overcome this?
I see many apps that do this so its a very common problem that may already be solved as a framework.
Example:
UICollectionView is actually of arbitrary layout. It so happens that the default is UICollectionViewFlowLayout which is a grid, but you can change it to anything by implmenting your own instance of the UICollectionViewLayout protocol. Int the case you cited its pretty easy. The width of the cells is the collectionview (width minus the padding) divided by two. The height is the aspect ratio times the width + the spacing + the label height. all the cells with indices divisible by 2 go in the right column and the rest go in the left column. It should be easy to calculate these values for layoutAttributesForItem(at:). Unfortunately its a bit harder to calculate for collectionViewContentSize. Assuming your collectionview is sufficiently small I think its best to just precalculate all of the hieghts and use the cached values for these functions.
There're a lot of open sources on github You can refer to.
https://github.com/zhangsuya/SYStickHeaderWaterFall

iOS: Correct method to set or increase text field width

Our UITextField instances are using the "default" settings. They auto expand based on user input. We'd like to set them to a larger initial width so they don't have to increase their width. What is the correct way to do this to while maintaining an 'adaptive' layout? Or is this just contrary to iOS best practices and we should leave it as is?
To determine a view's size the autolayout uses two methods:
- (CGSize)intrisicContentSize //with
- (UILayoutPriority)contentCompressionResistancePriorityForAxis:(UILayoutConstraintAxis)axis;
- (UILayoutPriority)contentHuggingPriorityForAxis:(UILayoutConstraintAxis)axis;
and
width and height constrtaints (size constraints)
//also the autolayot can use inner constraints, but here it is not important
If you have size constraints and intrisic content size with different values, you shout set priority for constraints and for intrisicContentSize.
In your case, you can set low priority for contentHuggingPriorityForAxis for horizontal axis. Set middle priority for width constraint. Set Hight priority for contentCompressionResistancePriorityForAxis for the horizontal axis.
After that, if text be smaller then width constraint, the textField will have width same to constant of the width constraint. Then text will have more width then constraint, the textField will grow out of the width constraint.
Also I recommend for you add constraint with "<=" relation for max width and required priority

Is it efficient to use max float for boundingRectWithSize for height

In Objective-C when calculating the size required for given text, we use boundingRectWithSize:options:attributes:context: with the size parameter set to the constraining size. Width is usually where the text should break with height being the more flexible axis. Mostly I have seen CGFLOAT_MAX used for height. I've also seen the height specified to the bounds of a parent view (or some similar reasonable value).
[someText boundingRectWithSize:CGSizeMake(maxWidth, CGFLOAT_MAX) options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size
My question is, does it matter? Is one method more efficient than the other?
It has nothing to do with "efficient". It has to do with what they mean and what they do.
CGFLOAT_MAX is a way of guaranteeing that the height can be as big as it needs to be. Use it if you don't care how tall the text can be. It is, in effect, an unlimited potential height (though of course the actual height will not be unlimited).
Use a limited height if you do care how tall the text can be. In other words, if you have a reason to want the layout to fail if it can't fit in a certain height, limit the height. You'll know you've failed if the resulting width or height exceeds the width or height you specified (or, in the case of your code, if you get a zero size).

Resources