[英]Swift: Unable to resize collectionViewCells in SplitViewController
我正在尝试调整SplitViewController
的masterViewController
内的collectionView
单元格,但调整大小不起作用。 我已经实现了必要的viewWillTransition
和invalidateLayout
,如果它没有放在splitViewController
中,结果会很好。 就我而言,我有全屏单元格大小。
这是我的实现:
//This CollectionController is housed inside a TabBarController.
//The TabBarController is the masterViewController
class CollectionController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.backgroundColor = .gray
cv.dataSource = self
cv.delegate = self
layout.scrollDirection = .horizontal
cv.isPagingEnabled = true
cv.showsHorizontalScrollIndicator = false
cv.showsVerticalScrollIndicator = false
cv.contentInsetAdjustmentBehavior = .always
cv.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
var spacing: CGFloat = 16
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
collectionView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = .blue
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 16
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 16
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let layoutFrame = view.safeAreaLayoutGuide.layoutFrame
let size = CGSize(width: layoutFrame.width, height: layoutFrame.height)
print("SizeForItem", size)
return setUpCellSize(size: size)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
print("Transit1", size)
layout.itemSize = setUpCellSize(size: size) //With or without this makes no difference
layout.invalidateLayout()
print("Transit2", size)
}
}
func setUpCellSize(size: CGSize) -> CGSize {
return size
}
}
这是纯粹在TabBarController
中实现的结果,即不在splitViewController
中实现。 注意到单元格(蓝色)位于状态栏下方。 结果是预期和期望的。
这是在splitViewController
中实现的结果。 注意到在第一次旋转到横向时,单元格位于状态栏上方。 当旋转回纵向时,单元格没有调整回全屏。
如果将collectionView 放在masterViewController 中,是否还有其他需要实现的东西?
编辑
我在sizeForItem
和viewWillTransition
中添加了打印语句。 事实证明,在第二次旋转时, viewWillTransition
中的新大小没有传递给sizeForItem
。
甚至对setupCellSize
的显式调用也没有正确更新。 它还给出The behavior of the UICollectionViewFlowLayout is not defined
警告。 见 gif(当 iPad 处于横向模式时,Gif 开始)。
另请注意,当 iPad 从横向 -> 纵向旋转时,蓝色单元格锚定到 statusBar 的底部和 tabBar 的顶部。 这是所希望的。 然后当从纵向 -> 横向旋转回来时,蓝色单元格超过状态栏并进入 tabBar 下方。 这不是我想要的。
好的,我已经设法解决了这个问题。 @Glenn 的解决方案有部分帮助。 帮助完全解决这个问题的部分来自这篇文章。
首先,实施@Glenn 的解决方案,将CollectionController
嵌入UINavigationController
并隐藏导航栏(因为我不想要导航栏)。
其次,在viewWillLayoutSubviews
中添加invalidateLayout
。
完整代码:
class CollectionController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.backgroundColor = .gray
cv.dataSource = self
cv.delegate = self
cv.isPagingEnabled = true
cv.alwaysBounceHorizontal = true
cv.showsHorizontalScrollIndicator = false
cv.showsVerticalScrollIndicator = false
cv.contentInsetAdjustmentBehavior = .always
cv.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
var spacing: CGFloat = 16
//FIRST
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.isHidden = true
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
collectionView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = .blue
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let layoutFrame = view.safeAreaLayoutGuide.layoutFrame
let size = CGSize(width: layoutFrame.width, height: layoutFrame.height)
return setUpCellSize(size: size)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
collectionView.collectionViewLayout.invalidateLayout()
}
//SECOND
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
collectionView.collectionViewLayout.invalidateLayout()
}
func setUpCellSize(size: CGSize) -> CGSize {
return size
}
}
结果就像这样,蓝色单元格很好地锚定在statusBar
的底部和tabBar
的顶部。
附带说明一下,我在这个线程中尝试了一些解决方案,但这些对我不起作用:
如果有人决定在splitViewController
中尝试解决相同情况的解决方案,请注意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.