我有UICollectionView
使用流式布局,我试图获得与具有可读内容宽度的UITableViewController
相同的边距。
我最接近匹配此布局行为的是在UICollectionViewController
中嵌入UIViewController
并具有嵌入式视图"遵循可读宽度"。
这里的蓝绿色是UIViewController
,鲑鱼的颜色是UICollectionViewController
。问题是青色区域没有滚动UICollectionView
,滚动指示器也不像你期望的那样沿着屏幕的边缘。
我的问题是:
如何在不必嵌入
UICollectionViewController
的情况下实现此布局?
我的猜测是,我可以以某种方式设置UICollectionView
左右部分插图以匹配可读内容指南边距,并通过覆盖viewWillTransition(to size: with coordinator:)
并观察UIContentSizeCategoryDidChange
通知来更新它们,但我和#39;我不知道该怎么做。
答案 0 :(得分:0)
您的预感是正确的,最简单的方法是通过集合视图的insetForSection
。以我的经验,这是必需的:
directionalLayoutMargins
作为插图(使用.leading
和。trailing
collectionView.insetsLayoutMarginsFromSafeArea = false
禁用自动安全区域处理directionalLayoutMargins
手动设置集合视图的view.readableContentGuide.layoutFrame.origin.x
。请注意,我使用的是 view .visibleContentGuide,而不是collectionView
的。directionalLayoutMargins
,以完全相同的方式更新viewLayoutMarginsDidChange
仍然很高兴知道如何在没有任何类型的容器的情况下完成此操作
答案 1 :(得分:0)
为了解决Swift 5.1和iOS 13的问题,您可以将流程布局的sectionInsetReference
属性设置为.fromLayoutMargins
,将集合视图的insetsLayoutMarginsFromSafeArea
属性设置为{{1} },然后将集合视图的layoutMargins
属性设置为与false
的插图匹配。
以下两个示例代码显示了可能的实现方式,以使收集视图的内容宽度可读。
readableContentGuide
UICollectionViewDelegateFlowLayout
import UIKit
class CollectionViewController: UICollectionViewController {
let inset: CGFloat = 10
let minimumLineSpacing: CGFloat = 10
let minimumInteritemSpacing: CGFloat = 10
let cellsPerRow = 5
override func viewDidLoad() {
super.viewDidLoad()
title = "Demo"
guard let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else { return }
layout.sectionInsetReference = .fromLayoutMargins
collectionView.insetsLayoutMarginsFromSafeArea = false
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
}
override func viewWillLayoutSubviews() {
let xOrigin = view.readableContentGuide.layoutFrame.origin.x
collectionView.layoutMargins = UIEdgeInsets(top: 0, left: xOrigin, bottom: 0, right: xOrigin)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 59
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
cell.backgroundColor = UIColor.orange
return cell
}
}
extension CollectionViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: inset, left: inset, bottom: inset, right: inset)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return minimumLineSpacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return minimumInteritemSpacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let marginsAndInsets = inset * 2 + collectionView.layoutMargins.left + collectionView.layoutMargins.right + minimumInteritemSpacing * CGFloat(cellsPerRow - 1)
let itemWidth = ((collectionView.bounds.size.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down)
return CGSize(width: itemWidth, height: itemWidth)
}
}
ColumnFlowLayout.swift
UICollectionViewFlowLayout
CollectionViewController.swift
import UIKit
class ColumnFlowLayout: UICollectionViewFlowLayout {
let cellsPerRow: Int
init(cellsPerRow: Int, minimumInteritemSpacing: CGFloat = 0, minimumLineSpacing: CGFloat = 0, sectionInset: UIEdgeInsets = .zero) {
self.cellsPerRow = cellsPerRow
super.init()
self.sectionInsetReference = .fromLayoutMargins
self.minimumInteritemSpacing = minimumInteritemSpacing
self.minimumLineSpacing = minimumLineSpacing
self.sectionInset = sectionInset
}
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 = sectionInset.left + sectionInset.right + collectionView.layoutMargins.left + collectionView.layoutMargins.right + minimumInteritemSpacing * CGFloat(cellsPerRow - 1)
let itemWidth = ((collectionView.bounds.size.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down)
itemSize = CGSize(width: itemWidth, height: itemWidth)
}
}
在iPhone Xs Max上显示: