Reputation: 644
I am using compositional layout in a SwiftUI app.
I am using the list version of UICollectionViewCompositionalLayout and want the list to ignore the top safe area. I can't find any sources on how to do this.
Adding "collectionView.contentInsetAdjustmentBehavior = .never" messes up the scrolling for a second and crashes the app outright due to an error "recursive layout loop. This can happen when self-sizing views do not return consistent sizes, or the collection view's frame/bounds/contentOffset is being constantly adjusted"
I have added a minimal reproducible example below. You can literally copy and paste to see the issue.
struct ContentView: View {
var body: some View {
GeometryReader { geo in
VCRepresentable()
}
.ignoresSafeArea(edges: .top)
}
}
struct VCRepresentable: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
return LayoutVC()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
}
}
struct Item: Hashable {
let name: String
}
class LayoutVC: UIViewController {
enum Section: CaseIterable {
case main
}
let items = [Item(name: "Item 1"), Item(name: "Item 2"), Item(name: "Item 3")]
var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
override func viewDidLoad() {
super.viewDidLoad()
collectionView = UICollectionView(frame: .zero, collectionViewLayout: createLayout())
collectionView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: view.topAnchor),
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
configureDataSource()
applySnapshot()
}
func createLayout() -> UICollectionViewLayout {
var listConfiguration = UICollectionLayoutListConfiguration(appearance: .grouped)
listConfiguration.headerMode = .none
listConfiguration.headerTopPadding = 0
let layout = UICollectionViewCompositionalLayout.list(using: listConfiguration)
return layout
}
func configureDataSource() {
dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { [unowned self]collectionView, indexPath, item in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
if indexPath.row == 0 {
cell.contentConfiguration = UIHostingConfiguration {
Color.blue
.frame(height: 100)
}
.margins(.all, 0)
} else {
cell.contentConfiguration = UIHostingConfiguration {
HStack {
Text("\(items[indexPath.row])")
Spacer()
}
.frame(height: 44)
}
}
return cell
}
}
func applySnapshot() {
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.main])
snapshot.appendItems(items)
dataSource.apply(snapshot, animatingDifferences: false)
}
}
What I basically want:
Upvotes: 0
Views: 67