为了解决您使用 Swift 5.1 和 iOS 13 的问题,您可以将流布局的 sectionInsetReference 属性设置为 .fromContentInset,将集合视图的 insetsLayoutMarginsFromSafeArea 属性设置为 false,并将集合视图的 @987654324 设置为@s 匹配 view 的 readableContentGuide 的插图。
以下示例代码显示了一个可能的实现,以便拥有一个具有可读内容宽度的集合视图:
ViewController.swift
import UIKit
class ViewController: UIViewController {
let collectionView = UICollectionView(
frame: .zero,
collectionViewLayout: ColumnFlowLayout(cellsPerRow: 5)
)
var collectionViewNeedsLayout = true
override func viewDidLoad() {
super.viewDidLoad()
title = "Demo"
view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: view.topAnchor),
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
collectionView.backgroundColor = .white
collectionView.insetsLayoutMarginsFromSafeArea = false
collectionView.dataSource = self
collectionView.register(Cell.self, forCellWithReuseIdentifier: "Cell")
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if collectionViewNeedsLayout {
let margin = view.readableContentGuide.layoutFrame.origin.x
collectionView.contentInset.left = margin
collectionView.contentInset.right = margin
collectionViewNeedsLayout = false
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
collectionViewNeedsLayout = true
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 59
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! Cell
return cell
}
}
ColumnFlowLayout.swift
import UIKit
class ColumnFlowLayout: UICollectionViewFlowLayout {
let cellsPerRow: Int
init(cellsPerRow: Int) {
self.cellsPerRow = cellsPerRow
super.init()
self.sectionInsetReference = .fromContentInset
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepare() {
super.prepare()
guard let collectionView = collectionView else { return }
let marginsAndInsets = collectionView.contentInset.left + collectionView.contentInset.right + sectionInset.left + sectionInset.right + minimumInteritemSpacing * CGFloat(cellsPerRow - 1)
let itemWidth = ((collectionView.bounds.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down)
itemSize = CGSize(width: itemWidth, height: itemWidth)
}
}
Cell.swift
import UIKit
class Cell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
contentView.backgroundColor = .orange
}
required init?(coder: NSCoder) {
fatalError("not implemnted")
}
}
在 iPhone 11 Pro Max 上显示: