如何计算从具有自动布局宽高比约束的xib加载的UICollectionViewCell的大小?

时间:2022-08-27 10:46:20

I have a UICollectionViewCell that is loaded from a xib and stored in a property to help with calculating cell sizes for my collection view. The collection view always has only one column, so the cells vary in their widths based on the phone the user has (iphone 5/6/6+). The xib has an image view with an aspect ratio that must remain constant for all phone sizes.

我有一个UICollectionViewCell,它从xib加载并存储在属性中,以帮助计算我的集合视图的单元格大小。集合视图始终只有一列,因此单元格的宽度根据用户的手机而有所不同(iphone 5/6/6 +)。 xib的图像视图的宽高比必须对所有手机尺寸保持不变。

The problem I run into stems from this configuration. I cannot seem to make the cell size the way I want based on a fixed width. My sizeForItemAtIndexPath: method looks like this:

我遇到的问题源于这种配置。基于固定的宽度,我似乎无法按照我想要的方式制作单元尺寸。我的sizeForItemAtIndexPath:方法如下所示:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    self.sizingCell.frame.size.width = self.flowLayout.fullViewSectionSize.width;
    [self configureCell:self.sizingCell atIndexPath:indexPath];
    [self.sizingCell setNeedsLayout];
    [self.sizingCell layoutIfNeeded];
    CGSize size = [self.sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    return size;
}

I'm doing what I've read I'm supposed to for dynamic size calculations with an off-screen cell, but the problem is that when layoutIfNeeded is called, I get an unsatisfiable constraint exception with my constraints and an extra constraint that sets the height of the cell to be the height of it as defined in the xib. The system never breaks this extra height constraint I did not add, so the height of the cell is always this incorrect height of the view at design time in the xib.

我正在做的事情我已经读过了我应该用离屏单元格进行动态大小计算,但问题是当调用layoutIfNeeded时,我得到一个不可满足的约束异常,我的约束和一个额外的约束设置单元格的高度为xib中定义的高度。系统永远不会破坏我没有添加的额外高度约束,因此单元格的高度始终是xib中设计时视图的不正确高度。

Can I somehow remove this extraneous constraint that causes this to not work? Is there some other setting to set here that does what I need? I've tried turning off translatesAutoResizingMaskIntoConstraints to no avail as well. How can I make a xib-loaded cell figure out it's size based on constraints involving aspect ratios?

我可以以某种方式删除这个无关的约束,导致这不起作用?是否有其他设置在这里设置我需要的东西?我试过关闭translatesAutoResizingMaskIntoConstraints也无济于事。如何根据涉及纵横比的约束使xib加载的单元格看出它的大小?

Edit:

If you want to see what i'm talking about in action, I put together a swift version of this in a github repo here: https://github.com/klundberg/Autolayout-CollectionViewExample

如果你想看看我正在谈论的是什么,我在这里的github repo中整理了一个快速版本:https://github.com/klundberg/Autolayout-CollectionViewExample

1 个解决方案

#1


I figured this out with a little workaround.

我想通过一些解决方法来解决这个问题。

Originally, my xib was a collection view cell whose subview was an image with the aspect ratio constraint in there. This conflicted with the default constraints that iOS adds to these cells (named "UIView-Encapsulated-Layout-Height/Width"). My solution was to introduce one level of view in between the cell and the views i cared about laying out, so now this is a cell that contains a container view which contains my image view. The container view does not get the encapsulated layout constraints applied to it, so if I make an IBOutlet for it and call systemLayoutSizeFittingSize: on that view (instead of the contentView after setting its width, it will correctly calculate the height with no constraint conflicts.

最初,我的xib是一个集合视图单元,其子视图是一个具有宽高比约束的图像。这与iOS添加到这些单元格的默认约束(名为“UIView-Encapsulated-Layout-Height / Width”)相冲突。我的解决方案是在单元格和我关心布局的视图之间引入一个级别的视图,所以现在这是一个包含容器视图的单元格,其中包含我的图像视图。容器视图没有获得应用于它的封装布局约束,因此如果我为它创建一个IBOutlet并在该视图上调用systemLayoutSizeFittingSize:(而不是在设置其宽度后的contentView,它将正确计算高度而没有约束冲突。

#1


I figured this out with a little workaround.

我想通过一些解决方法来解决这个问题。

Originally, my xib was a collection view cell whose subview was an image with the aspect ratio constraint in there. This conflicted with the default constraints that iOS adds to these cells (named "UIView-Encapsulated-Layout-Height/Width"). My solution was to introduce one level of view in between the cell and the views i cared about laying out, so now this is a cell that contains a container view which contains my image view. The container view does not get the encapsulated layout constraints applied to it, so if I make an IBOutlet for it and call systemLayoutSizeFittingSize: on that view (instead of the contentView after setting its width, it will correctly calculate the height with no constraint conflicts.

最初,我的xib是一个集合视图单元,其子视图是一个具有宽高比约束的图像。这与iOS添加到这些单元格的默认约束(名为“UIView-Encapsulated-Layout-Height / Width”)相冲突。我的解决方案是在单元格和我关心布局的视图之间引入一个级别的视图,所以现在这是一个包含容器视图的单元格,其中包含我的图像视图。容器视图没有获得应用于它的封装布局约束,因此如果我为它创建一个IBOutlet并在该视图上调用systemLayoutSizeFittingSize:(而不是在设置其宽度后的contentView,它将正确计算高度而没有约束冲突。