我使用UICollectionViewFlowLayout.automaticSize创建了一个水平滚动集合视图。 集合视图的高度为40 单元格的高度为40,这是我在初始化时通过autolayou设置的。
问题在于只有第一个显示的单元格显示收集视图 具有50x50的尺寸,可以覆盖通过代码手动设置的40我的自动布局高度。
我检查了willDisplayCell委托方法的大小。
当我滚动集合视图以显示其他单元格时,每个新显示的单元格 细胞具有适当的大小,高度为40。
尽管尺寸为50x50(已记录)的单元格可以正确显示(似乎高度为40)在屏幕上。
由此,我在模拟器上运行应用程序时收到错误消息(记录),并且 如果我在真实设备(iPhone8 iOS 11)上运行,则该应用程序将崩溃。
import UIKit
class HorizontalTabNavigationViewController: UIViewController {
// MARK: - Collection View
private lazy var navigationCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.backgroundColor = .white
cv.dataSource = self
cv.delegate = self
return cv
}()
private typealias Cell = HorizontalTabNavigationCell
private let cellId: String = "cell"
// MARK: - Property
var items: [HorizontalTabNavigationItem] = []
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
self.view.translatesAutoresizingMaskIntoConstraints = false
navigationCollectionView.register(Cell.self, forCellWithReuseIdentifier: cellId)
navigationCollectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
setupSubviews()
}
private func setupSubviews() {
view.addSubview( navigationCollectionView )
[
navigationCollectionView.topAnchor .constraint(equalTo: view.topAnchor),
navigationCollectionView.leftAnchor .constraint(equalTo: view.leftAnchor),
navigationCollectionView.rightAnchor .constraint(equalTo: view.rightAnchor),
navigationCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
].forEach { $0.isActive = true }
}
}
extension HorizontalTabNavigationViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! Cell
//cell.setProperties(item: items[indexPath.row])
//print("Cell for item: \(items[indexPath.row].title)")
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print("Cell Size on willDispaly cell")
print(cell.bounds.size)
print("\n")
}
}
extension HorizontalTabNavigationViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 5 // Defines horizontal spacing between cells
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .zero
}
}
class HorizontalTabNavigationCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupSelfHeight()
self.backgroundColor = .orange
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupSelfHeight() {
self.heightAnchor.constraint(equalToConstant: 40).isActive = true
self.widthAnchor.constraint(equalToConstant: 120).isActive = true
}
}
答案 0 :(得分:0)
我通过将自定义尺寸设置为流布局解决了这个问题。
受到马纳夫(Manav)对以下问题的回答的启发。
private lazy var navigationCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
// [Here is the answer]
// Set Height equal or less than the height of the collection view.
// This is applied on first display of cells and
// will also not affect cells auto sizing.
layout.estimatedItemSize = CGSize(width: 200, height: 40) // UICollectionViewFlowLayoutAutomaticSize
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.showsHorizontalScrollIndicator = false
cv.backgroundColor = .white
cv.dataSource = self
cv.delegate = self
return cv
}()