如何在iOS 8中获取UICollectionViewCells的自动布局大小? (systemLayoutSizeFittingSize在iOS 8中返回零高度的大小)

时间:2014-08-12 13:09:40

标签: ios objective-c autolayout ios8

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

以下是代码的作用:

要确定iOS 7中UICollectionView中单元格的大小,我使用自动布局在xib文件中定义的单元格上使用systemLayoutSizeFittingSize:。大小取决于UILabel的字体大小,该UICollectionViewCell是我的xib文件中UIFontTextStyleBody的子视图。标签的字体设置为+ (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中的字体大小设置。

以下是代码本身:

 return [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

它在iOS 7中完美运行,但在iOS 8中运行不佳。不幸的是,我不知道为什么。

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

PS:使用

 return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

而不是

{{1}}
如某人所暗示的那样,并没有任何区别。

8 个答案:

答案 0 :(得分:8)

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

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

您的手机应如下所示:手机 - > containerView - >子视图

适用于ios7和ios7。 iOS8上。

据说在ios8上,您所要做的就是设置estimateSize&单元格将自动自动调整大小。显然,自从测试版6开始不起作用。

答案 1 :(得分:7)

这看起来像是一个正式的错误:我提交了一份报告,该报告因this one

的副本而被关闭

将在Beta 6退出时报告。

[更新:在iOS 8的GM种子中正常运行,该错误已被Apple关闭。]

答案 2 :(得分:4)

我们现在正在使用解决方法,复制如下。希望在iOS 8发布之前解决这些问题,我们可以删除它。 (该kludge假设了解Apple的隐式contentView行为,我们必须破解IB出口引用我们转移的任何约束。)

我们注意到他们还在升级过程中从故事板/ NIB中删除了所有autoresizingMasks,这是合理的,因为它应该是自动布局,但是集合视图仍然会回归到spring&支柱。也许在清除中忽略了这一点?

- 丹

/**
 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];
}

答案 3 :(得分:0)

这是在iOS7设备上运行的xCode6和iOS 8 SDK中的错误:) 这几乎是我的一天。最后,它使用了UICollectionViewCell子类中的以下代码。我希望这将在下一个版本中修复

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

答案 4 :(得分:0)

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

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

答案 5 :(得分:0)

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

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

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

3)根据您的要求在接口构建器中正确设置约束,在接口构建器中有一些无法添加的约束,但是您可以在viewController的viewDidLoad中添加它们。

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

答案 6 :(得分:0)

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

的优秀底层空间

答案 7 :(得分:-1)

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