我有一个UICollectionViewCell
,里面有一个UICollectionView
和UICollectionViewFlowLayout
。我正在使单元格成为集合 View 的委托(delegate)和数据源。我符合UICollectionViewDelegateFlowLayout
并实现collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
(并返回正确的大小)。
但是,当我调用layout.itemSize.height
时,我得到了默认的高度50。
class MyCell: UICollectionViewCell {
fileprivate lazy var collectionView: UICollectionView = {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(SomeOtherCell.self, forCellWithReuseIdentifier: SomeOtherCell.reuseIdentifier)
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
return collectionView
}()
fileprivate lazy var layout: UICollectionViewFlowLayout? = {
let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
layout?.scrollDirection = .horizontal
layout?.sectionInset = UIEdgeInsets.zero
return layout
}()
override func sizeThatFits(_ size: CGSize) -> CGSize {
collectionView.frame = CGRect(x: layoutMargins.left, y: origin.y, width: width, height: layout.itemSize.height)
// layout.itemSize.height is always 50
}
}
extension MyCell: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
guard tags.count != 0 else {
return .zero
}
let tag = Tag(text: tags[indexPath.item], index: indexPath.item)
placeholderCell.configure(with: tag)
let size = placeholderCell.getFrame(at: .zero, fitting: placeholderCell.width, alignedBy: semanticContentAttribute, apply: false).size
collectionViewWidth += size.width
// this size is always correct, that's what I want when I call layout.itemSize.height
return size
}
}
最佳答案
问题
itemSize
仅在委托(delegate)未实现collectionView(_:layout:sizeForItemAt :)方法且中没有提及itemSize
将从collectionView(_:layout:sizeForItemAt:)
返回值的情况下使用。 它们是2个不同的值。这就是为什么itemSize
实现后sizeForItemAt
不会改变的原因因此,使用
layout.itemSize.height
时默认值为(50)才有意义。 您的问题有什么解决方案?
collectionView
上的所有单元格都具有相同的大小,建议您为itemSize
设置一个值,并且不要实现collectionView(_:layout:sizeForItemAt:)
方法(删除UICollectionViewDelegateFlowLayout
的扩展名)。class MyCell: UICollectionViewCell {
fileprivate lazy var collectionView: UICollectionView = {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
// collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(SomeOtherCell.self, forCellWithReuseIdentifier: SomeOtherCell.reuseIdentifier)
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
return collectionView
}()
fileprivate lazy var layout: UICollectionViewFlowLayout? = {
let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
layout?.scrollDirection = .horizontal
layout?.sectionInset = UIEdgeInsets.zero
// Calculate and change |itemSize| here
layout?.itemSize = YOUR_CELL_SIZE_AFTER_CALCULATED
return layout
}()
override func sizeThatFits(_ size: CGSize) -> CGSize {
collectionView.frame = CGRect(x: layoutMargins.left, y: origin.y, width: width, height: layout.itemSize.height)
// layout.itemSize.height is |YOUR_CELL_SIZE_AFTER_CALCULATED.height|
}
}
collectionView
大小不同,则需要使用UICollectionView's layoutAttributesForItem(at:) method。在IndexPath处获取UICollectionViewLayoutAttributes并使用layoutAttributes.size进行计算layoutAttributes.size是从
collectionView(_:layout:sizeForItemAt:)
返回的值let indexPath = // IndexPath you need to use to calculate
let layoutAttributes : UICollectionViewLayoutAttributes? = collectionView.layoutAttributesForItem(at: indexPath)
// Use this value to calculate |collectionView| frame
print(layoutAttributes?.size)
关于ios - 尽管实现了sizeForItemAt,UICollectionViewFlowLayout单元格的大小从未改变,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47894895/