对于我们使用的 UICollectionView 的动态高度单元格,
if let layout = self.collectionViewLayout as? UICollectionViewFlowLayout {
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
}
在高度和宽度的适当约束下,它适用于 iOS 11.* 版本,但它会破坏并且不会使单元格在 iOS 12.0 中动态化
对于我们使用的 UICollectionView 的动态高度单元格,
if let layout = self.collectionViewLayout as? UICollectionViewFlowLayout {
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
}
在高度和宽度的适当约束下,它适用于 iOS 11.* 版本,但它会破坏并且不会使单元格在 iOS 12.0 中动态化
就我而言,我通过向单元格的 contentView 显式添加以下约束来解决此问题。
class Cell: UICollectionViewCell {
// ...
override func awakeFromNib() {
super.awakeFromNib()
// Addresses a separate issue and prevent auto layout warnings due to the temporary width constraint in the xib.
contentView.translatesAutoresizingMaskIntoConstraints = false
// Code below is needed to make the self-sizing cell work when building for iOS 12 from Xcode 10.0:
let leftConstraint = contentView.leftAnchor.constraint(equalTo: leftAnchor)
let rightConstraint = contentView.rightAnchor.constraint(equalTo: rightAnchor)
let topConstraint = contentView.topAnchor.constraint(equalTo: topAnchor)
let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
NSLayoutConstraint.activate([leftConstraint, rightConstraint, topConstraint, bottomConstraint])
}
}
这些约束已经存在于单元格的 xib 中,但不知何故,它们对于 iOS 12 来说还不够。
建议collectionView.collectionViewLayout.invalidateLayout()
在各个地方调用的其他线程对我的情况没有帮助。
此处的示例代码:https ://github.com/larrylegend/CollectionViewAutoSizingTest
这将解决方法应用于https://medium.com/@wasinwiwongsak/uicollectionview-with-autosizing-cell-using-autolayout-in-ios-9-10-84ab5cdf35a2的教程中的代码:
基于ale84
的回答,并且由于我需要在多个地方修复 iOS 12,我创建了一个 UICollectionViewCell 扩展,我将其命名为 UICollectionViewCell+iOS12:
extension UICollectionViewCell {
/// This is a workaround method for self sizing collection view cells which stopped working for iOS 12
func setupSelfSizingForiOS12(contentView: UIView) {
contentView.translatesAutoresizingMaskIntoConstraints = false
let leftConstraint = contentView.leftAnchor.constraint(equalTo: leftAnchor)
let rightConstraint = contentView.rightAnchor.constraint(equalTo: rightAnchor)
let topConstraint = contentView.topAnchor.constraint(equalTo: topAnchor)
let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
NSLayoutConstraint.activate([leftConstraint, rightConstraint, topConstraint, bottomConstraint])
}
}
然后在您的集合视图单元格中,我们执行以下操作(如果您的单元格是在 IB 中创建的):
override func awakeFromNib() {
super.awakeFromNib()
if #available(iOS 12, *) { setupSelfSizingForiOS12(contentView: contentView) }
}
上述答案的目标 C 版本:
-(void)awakeFromNib{
[super awakeFromNib];
if (@available(iOS 12.0, *)) {
// Addresses a separate issue and prevent auto layout warnings due to the temporary width constraint in the xib.
self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
// Code below is needed to make the self-sizing cell work when building for iOS 12 from Xcode 10.0:
NSLayoutConstraint *leftConstraint = [self.contentView.leftAnchor constraintEqualToAnchor:self.leftAnchor constant:0];
NSLayoutConstraint *rightConstraint = [self.contentView.rightAnchor constraintEqualToAnchor:self.rightAnchor constant:0];
NSLayoutConstraint *topConstraint = [self.contentView.topAnchor constraintEqualToAnchor:self.topAnchor constant:0];
NSLayoutConstraint *bottomConstraint = [self.contentView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor constant:0];
[NSLayoutConstraint activateConstraints:@[leftConstraint, rightConstraint, topConstraint, bottomConstraint]];
}
}
对于像我这样的 Objective-C 爱好者 ;) 干杯 !!!
我也有同样的问题。使用 UILabels 来调整 collectionview 的大小。如果我collectionView.collectionViewLayout.invalidateLayout()
在重新加载数据之前运行它可以很好地调整标签的大小。
还是不太对。我很难想象,因为我在模拟器和设备上运行它。
我设法通过将这样的代码放入我的 UICollectionViewCell 子类来解决这个问题
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
[self updateConstraintsIfNeeded];
CGSize size = [self systemLayoutSizeFittingSize:CGSizeMake(1000, 1000)];
CGRect alteredRect = layoutAttributes.frame;
alteredRect.size = size;
layoutAttributes.frame = alteredRect;
return layoutAttributes;
}
并像这样子类化 UICollectionView
@interface CustomCollectionView ()
@property (nonatomic) BOOL shouldInvalidateLayout;
@end
@implementation CustomCollectionView
- (void)layoutSubviews {
[super layoutSubviews];
if (self.shouldInvalidateLayout) {
[self.collectionViewLayout invalidateLayout];
self.shouldInvalidateLayout = NO;
}
}
- (void)reloadData {
self.shouldInvalidateLayout = YES;
[super reloadData];
}
@end