UICollectionViewCell systemLayoutSizeFittingSize返回不正确的宽度

我一直在玩dynamicUICollectionViewCell的,并已注意到在iOS 8上调用cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)上的UICollectionViewCell cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)返回不正确的宽度。 目前解决这个问题的唯一解决方法是显式地添加宽度约束来强制单元格的宽度。 下面的代码用在Cell子类中:

 func calculatePreferredHeightForFrame(frame: CGRect) -> CGFloat { var newFrame = frame self.frame = newFrame let widthConstraint = NSLayoutConstraint(item: contentView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: CGRectGetWidth(frame)) contentView.addConstraint(widthConstraint) self.setNeedsUpdateConstraints() self.updateConstraintsIfNeeded() self.setNeedsLayout() self.layoutIfNeeded() let desiredHeight: CGFloat = self.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height newFrame.size.height = CGFloat(ceilf(Float(desiredHeight))) contentView.removeConstraint(widthConstraint) return CGRectGetHeight(newFrame) } 

我知道,与iOS 8和dynamicUICollectionViewFlowLayout UICollectionViewCell的contentView处理约束不同,但是有什么我在这里失踪? 为了确保systemLayoutSizeFittingSize在单元格上使用特定的宽度,需要做些什么?

我也遇到过这个post( 使用自动布局在UICollectionView中指定单元格的一个维度 ),并认为这可能实际上使我的问题无效。 也许UICollectionViewFlowLayout不是为只有一个dynamic维度的单元格devise的,但是这仍然不能解释为什么单元格会给出一个不寻常的宽度。

我面临同样的问题。 获取systemLayoutSize时,关键是使用优先级。

 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { if (!self.prototypeCell) { self.prototypeCell = [TrainingMenuCell new]; self.prototypeCell.contentView.translatesAutoresizingMaskIntoConstraints = NO; } [self configureCell:self.prototypeCell forIndexPath:indexPath]; [self.prototypeCell setNeedsLayout]; [self.prototypeCell layoutIfNeeded]; CGFloat width = CGRectGetWidth(collectionView.frame) - 12; CGSize fittingSize = UILayoutFittingCompressedSize; fittingSize.width = width; CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:fittingSize withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:UILayoutPriorityDefaultLow]; return size; }