UICollectionViewFlowLayout оценкамItemSize не работает должным образом с iOS12, хотя он отлично работает с iOS 11. *
Для ячеек динамической высоты UICollectionView мы используем,
if let layout = self.collectionViewLayout as? UICollectionViewFlowLayout {
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
}
с надлежащим ограничением высоты и ширины, он отлично работает с версиями iOS 11. *, но он ломается и не делает ячейки динамическими для iOS 12.0
Ответы
Ответ 1
В моем случае я решил это, явно добавив следующие ограничения в cellView.
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:
Ответ 2
Основываясь на ответе 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) }
}
Ответ 3
Вариант версии 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, таких как я;) приветствия !!!
Ответ 4
у меня та же проблема. используя UILabels для определения размера коллекции. если я запускаю collectionView.collectionViewLayout.invalidateLayout()
прежде чем перезагружать данные, он выполняет обычное задание по размеру меток.
все еще не совсем правильно. мне сложно понять, потому что я запускаю его на симуляторе против устройства.
Ответ 5
Мне удалось решить эту проблему, поставив такой код в мой подкласс 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