如何解决UICollectionViewCompositionalLayout 具有 .estimated 高度的意外行为
在水平正交部分中使用带有 .estimated 尺寸的 NSCollectionLayoutSize
会产生布局问题。单元格和补充视图存在布局冲突,滚动行为欠佳且间距不符合预期
import UIKit
class ViewController: UIViewController {
lazy var collectionView: UICollectionView = {
let layout = createLayout()
let collectionView = UICollectionView(frame: .zero,collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.dataSource = self
collectionView.backgroundColor = .systemBackground
collectionView.register(Cell.self,forCellWithReuseIdentifier: "cell")
collectionView.register(HeaderView.self,forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,withReuseIdentifier: "header")
return collectionView
}()
private func createLayout() -> UICollectionViewCompositionalLayout {
let sectionProvider = { (section: Int,layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
return self.horizontalLayout(layoutEnvironment: layoutEnvironment)
}
let config = UICollectionViewCompositionalLayoutConfiguration()
config.interSectionSpacing = 8
let layout = UICollectionViewCompositionalLayout(sectionProvider: sectionProvider,configuration: config)
return layout
}
private func supplementaryHeader() -> NSCollectionLayoutBoundarySupplementaryItem {
let titleSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),heightDimension: .estimated(50))
let titleSupplementary = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: titleSize,elementKind: UICollectionView.elementKindSectionHeader,alignment: .top)
return titleSupplementary
}
private func horizontalLayout(layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection {
let size = NSCollectionLayoutSize(widthDimension: .estimated(120),heightDimension: .estimated(50))
let item = NSCollectionLayoutItem(layoutSize: size)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: size,subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .continuous
section.interGroupSpacing = 8
section.contentInsets = NSDirectionalEdgeInsets(top: 16,leading: 16,bottom: 16,trailing: 16)
section.boundarySupplementaryItems = [supplementaryHeader()]
return section
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),collectionView.topAnchor.constraint(equalTo: view.topAnchor),collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
}
// MARK: UICollectionViewDataSource
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",for: indexPath)
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 25
}
func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView,viewForSupplementaryElementOfKind kind: String,at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionView.elementKindSectionHeader:
let header: HeaderView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader,withReuseIdentifier: "header",for: indexPath) as! HeaderView
return header
default: fatalError()
}
}
}
class Cell: UICollectionViewCell {
lazy var view: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .systemRed
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
fatalError("not implemented")
}
func configure() {
contentView.addSubview(view)
view.heightAnchor.constraint(equalToConstant: 80).isActive = true
view.widthAnchor.constraint(equalToConstant: 100).isActive = true
NSLayoutConstraint.activate([
view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),view.topAnchor.constraint(equalTo: contentView.topAnchor),view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
])
}
}
class HeaderView: UICollectionReusableView {
lazy var view: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .systemTeal
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
fatalError("not implemented")
}
func configure() {
addSubview(view)
view.heightAnchor.constraint(equalToConstant: 60).isActive = true
NSLayoutConstraint.activate([
view.leadingAnchor.constraint(equalTo: self.leadingAnchor),view.trailingAnchor.constraint(equalTo: self.trailingAnchor),view.topAnchor.constraint(equalTo: self.topAnchor),view.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。