У меня есть UICollectionView, с несколькими разделами и строками. Верхний и нижний колонтитулы, где это необходимо, фиксированного размера. Ячейки с автоматическим изменением размера
Вид ячейки имеет вид:
Зеленый цвет - ImageView
Оранжевый цвет - метки с numberOfLines = 0
.
Ячейка должна увеличить свой размер в соответствии с меткой numberOfLines
.
Я добился этого с помощью этого кода в MyCustomCell:
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
super.apply(layoutAttributes)
let autoLayoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)
let targetSize = CGSize(width: Constants.screenWidth/3.5, height: 0)
let autoLayoutSize = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: UILayoutPriority.required, verticalFittingPriority: UILayoutPriority.defaultLow)
let autoLayoutFrame = CGRect(origin: autoLayoutAttributes.frame.origin, size: autoLayoutSize)
autoLayoutAttributes.frame = autoLayoutFrame
return autoLayoutAttributes
}
Ячейки автоматически меняются, но ContentView (в голубом цвете) выровнен по центру по вертикали и по горизонтали.
I need to make it vertically align to Top.
У меня также была проблема с выравниванием верхних и нижних колонтитулов. Для этого я разделил на подклассы UICollectionViewFlowLayout
class MainCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func invalidationContext(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutInvalidationContext {
let context: UICollectionViewLayoutInvalidationContext = super.invalidationContext(forPreferredLayoutAttributes: preferredAttributes, withOriginalAttributes: originalAttributes)
let indexPath = preferredAttributes.indexPath
context.invalidateSupplementaryElements(ofKind: UICollectionView.elementKindSectionFooter, at: [indexPath])
context.invalidateSupplementaryElements(ofKind: UICollectionView.elementKindSectionHeader, at: [indexPath])
return context
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)
var topMargin = sectionInset.top
var leftMargin = sectionInset.left
var maxY: CGFloat = -1.0
attributes?.forEach { layoutAttribute in
guard layoutAttribute.representedElementCategory == .cell else {
return
}
if layoutAttribute.frame.origin.y >= maxY {
leftMargin = sectionInset.left
topMargin = sectionInset.top
}
layoutAttribute.frame.origin.x = leftMargin
leftMargin += layoutAttribute.frame.width + minimumInteritemSpacing
maxY = max(layoutAttribute.frame.maxY , maxY)
}
return attributes
}
}
Вот изображение, иллюстрирующее текущую ситуацию. Циан это contentView ячеек. Я должен привести его в соответствие с Top.
РЕДАКТИРОВАТЬ: Итак, я понял, что код UICollectionViewFlowLayout
создает больше ошибки, чем исправление проблемы. Я добавил layoutAttributesForElements
, чтобы выровнять ячейку по левому краю, если есть только одна ячейка. На самом деле он выровнял все мои клетки по левому краю. Код изменился как
class MainCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)
if attributes?.count == 1 {
if let currentAttribute = attributes?.first {
currentAttribute.frame = CGRect(x: self.sectionInset.left, y: currentAttribute.frame.origin.y, width: currentAttribute.frame.size.width, height: currentAttribute.frame.size.height)
}
}
return attributes
}
}
Теперь мои UICollectionViewCell
правильно выровнены по горизонтальному центру, за исключением того, что только одна ячейка будет выровнена по левому краю.
По-прежнему нет решения для вертикального выравнивания.