【问题标题】:How can a get the auto layout size of the UICollectionViewCells in iOS 8? (systemLayoutSizeFittingSize returns size with zero height in iOS 8)如何在 iOS 8 中获取 UICollectionViewCells 的自动布局大小? (systemLayoutSizeFittingSize 在 iOS 8 中返回高度为零的大小)
【发布时间】:2014-10-05 13:46:30
【问题描述】:

由于 iOS 8 [UIColletionViewCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] 返回高度为 0 的大小。

代码的作用如下:

为了确定 iOS 7 中 UICollectionView 中单元格的大小,我在使用自动布局的 xib 文件中定义的单元格上使用 systemLayoutSizeFittingSize:。大小取决于UILabel 的字体大小,它是我的xib 文件中UICollectionViewCell 的子视图。标签的字体设置为UIFontTextStyleBody。所以基本上单元格的大小取决于 iOS 7 中的字体大小设置。

这是代码本身:

+ (CGSize)cellSize {
    UINib *nib = [UINib nibWithNibName:NSStringFromClass([MyCollectionViewCell class]) bundle:nil];

    // Assumption: The XIB file only contains a single root UIView.
    UIView *rootView = [[nib instantiateWithOwner:nil options:nil] lastObject];

    if ([rootView isKindOfClass:[MyCollectionViewCell class]]) {
        MyCollectionViewCell *sampleCell = (MyCollectionViewCell*)rootView;
        sampleCell.label.text = @"foo"; // sample text without bar

        [sampleCell setNeedsLayout];
        [sampleCell layoutIfNeeded];

        return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    }

    return CGSizeZero;

}

它在 iOS 7 中运行良好,但在 iOS 8 中却不行。不幸的是,我不知道为什么。

如何在 iOS 8 中获取 UICollectionViewCells 的自动布局大小?

PS:使用

 return [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

而不是

 return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

正如有人可能建议的那样,没有任何区别。

【问题讨论】:

  • 我有同样的问题:在 iOS 7 [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height 返回正确的大小:在 iOS 8 上始终为 0。我发现这是使用 iOS7 或 iOS 8 SDK 构建的。抱歉,我还帮不上忙,但很高兴我不是唯一的一个!我已经提交了这个雷达:17959753
  • 我也有同样的问题。我整天都在玩它,找不到解决方案。将其更改为 collectionViewCell.contentView 没有帮助。
  • 我遇到了同样的问题,实验表明它可能与通过界面生成器添加的约束有关,这些约束是针对单元格视图而不是 cell.contentView。使用针对 contentView 的代码添加约束部分解决了这个问题
  • @AlexLittlejohn 它的 UICollectionViewCells IB 隐藏了内容视图,而 UITableViewCells 则没有,这使得很难知道在哪里创建了约束。就像问题中所说的 maremmle 一样, [sampleCell.contentView systemLayoutSizeFittingSize:...] 在表格视图单元格中工作。奇怪的是,它在 iOS 8 上肯定被破坏/更改了,因为在 iOS 8 设备上使用任一 SDK 构建都会失败。
  • @AlexLittlejohn 部分解决是什么意思?高度是否返回非零?

标签: ios objective-c autolayout ios8


【解决方案1】:

看起来这是一个正式的错误:我提交的报告已作为 this one 的副本关闭

Beta 6 发布后会报告。

[更新:在 iOS 8 的 GM 种子中正常工作,该 bug 已被 Apple 关闭。]

【讨论】:

  • 感谢您的努力。我应该也提交一个错误,还是你认为它会在 Beta6 中修复?
  • 我认为它现在已经引起人们的注意:如果它没有在 6 中修复,也许可以提交一个?
  • @maremmle 您应该始终提交错误,即使它是重复的。重复的错误报告将提高特定错误对 Apple 的可见性,使其更有可能尽早解决。
  • @MichaelG.Emmons 好的,我还向 Apple 提交了错误报告。
  • 我的错误报告也被标记为与 17962954 重复。openradar.appspot.com/search?query=17962954
【解决方案2】:

我们现在正在使用一种变通方法,复制如下。希望这些问题将在 iOS 8 发布之前得到解决,我们可以将其删除。 (kludge 假定知道 Apple 的隐式 contentView 行为,我们必须破解 IB 出口对我们转移的任何约束的引用。)

我们注意到他们还在升级期间从情节提要/NIB 中删除了所有 autoresizingMask,考虑到它应该是自动布局,这是有道理的,但集合视图仍然回归到弹簧和支柱。也许这在清洗中被忽略了?

--丹

/**
 Kludge around cell sizing issues for iOS 8 and deployment to iOS 7 when compiled for 8.  Call this on the collection view cell before it is used, such as in awakeFromNib.  Because this manipulates top-level constraints, any references to such initial constraints, such as from IB outlets, will be invalidated.

 Issue 1: As of iOS 8 Beta 5, systemLayoutSizeFittingSize returns height 0 for a UICollectionViewCell.  In IB, cells have an implicit contentView, below which views placed in IB as subviews of the cell are actually placed.  However, constraints set between these subviews and its superview are placed on the cell, rather than the contentView (which is their actual superview).  This should be OK, as a constraint among items may be placed on any common ancestor of those items, but this is not playing nice with systemLayoutSizeFittingSize.  Transferring those constraints to be on the contentView seems to fix the issue.

 Issue 2: In iOS 7, prior to compiling against iOS 8, the resizing mask of the content view was being set by iOS to width+height.  When running on iOS 7 compiled against iOS 8 Beta 5, the resizing mask is None, resulting in constraints effecting springs for the right/bottom margins.  Though this starts out the contentView the same size as the cell, changing the cell size, as we do in the revealing list, is not tracked by changing it's content view.  Restore the previous behavior.

 Moving to dynamic cell sizing in iOS 8 may circumvent this issue, but that remedy isn't available in iOS 7.
*/
+ (void)kludgeAroundIOS8CollectionViewCellSizingIssues:(UICollectionViewCell *)cell {

    // transfer constraints involving descendants on cell to contentView
    UIView *contentView = cell.contentView;
    NSArray *cellConstraints = [cell constraints];
    for (NSLayoutConstraint *cellConstraint in cellConstraints) {
        if (cellConstraint.firstItem == cell && cellConstraint.secondItem) {
            NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:contentView attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:cellConstraint.secondItem attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
            parallelConstraint.priority = cellConstraint.priority;
            [cell removeConstraint:cellConstraint];
            [contentView addConstraint:parallelConstraint];
        } else if (cellConstraint.secondItem == cell && cellConstraint.firstItem) {
            NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:cellConstraint.firstItem attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:contentView attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
            parallelConstraint.priority = cellConstraint.priority;
            [cell removeConstraint:cellConstraint];
            [contentView addConstraint:parallelConstraint];
        }
    }

    // restore auto-resizing mask to iOS 7 behavior
    contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [cell setNeedsUpdateConstraints];
    [cell updateConstraintsIfNeeded];
}

【讨论】:

  • 这或许也适用于iOS7?
【解决方案3】:

您需要做的是将所有内容包装在一个容器视图中,然后调用:

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

您的单元格应如下所示:单元格 -> containerView -> 子视图

这适用于 ios7 和 ios8。

假设在 ios8 上,您所要做的就是设置estimateSize & cell 会自动自动调整大小。显然,这在 beta 6 中不起作用。

【讨论】:

  • 看起来很奇怪,容器视图完全有效:我猜他们破坏了 UICollectionViewCell 中的某些内容:S
【解决方案4】:

这是 iOS 8 测试版中的一个错误。 最后它在 iOS 8 GB (Build 12A365) 上得到了修复。 所以对我来说,它现在可以使用我为 iOS 7 编写的相同代码。(请参阅问题)

【讨论】:

  • 感谢@all 参与讨论并向 Apple 报告错误。
【解决方案5】:

这是在 iOS7 设备上运行的 xCode6 和 iOS 8 SDK 中的一个错误 :) 它几乎让我的一天过得很充实。最后,它与 UICollectionViewCell 子类中的以下代码一起使用。希望下个版本能解决这个问题

- (void)setBounds:(CGRect)bounds {
    [super setBounds:bounds];
    self.contentView.frame = bounds;
}

【讨论】:

  • 我不推荐这个修复。如果您使用 systemLayoutSizeFittingSize: 它将无法正常工作,因为 contentView 不会成为约束层次结构的一部分。您需要对 contentView 进行约束或设置其 autoResizingMask。
【解决方案6】:

我在 UITableViewCells 和 iOS 7 上遇到了同样的问题(ios8 完美运行),但“Triet Luong”解决方案对我有用:

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

【讨论】:

    【解决方案7】:

    这不是错误,我一直在努力解决这个问题一段时间并尝试了不同的方法,我在下面给出了对我有用的步骤:

    1) 使用contentView [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

    2) 您可以创建自己的 contentView 并将 subViews 添加到 contentView,如果您使用自定义 contentView,请不要忘记将 contentView 的顶部、底部和左侧和右侧固定到 superView,如果您不要这样做,那么高度将为0,这也取决于您的要求。例如,不要将 contentView 的底部固定到 superView,以便视图的高度可以变化,但固定很重要,固定哪一个取决于您的要求。

    3)根据你的需求在interface builder中正确设置约束,有些约束不能在interface builder中添加,但是你可以在viewController的viewDidLoad中添加它们。

    所以我的 2 美分输入是,必须在界面构建器中正确设置约束,以便 systemLayoutSizeFittingSize:UILayoutFittingCompressedSize 返回正确的尺寸,这就是解决方案。

    【讨论】:

      【解决方案8】:

      也许你有一些错误的约束,你应该在你的 UIView 和 contentView 之间指定虚拟顶部空间和底部空间,我之前也遇到过这个问题,那是因为我只是指定了虚拟顶部空间,并且没有为 contentView 指定虚拟底部空间

      【讨论】:

        猜你喜欢
        • 2015-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-25
        • 2015-09-16
        • 1970-01-01
        • 2012-12-18
        • 2015-08-04
        相关资源
        最近更新 更多