我想显示一堆带有图像和标签的UICollection视图单元,并根据标签的宽度调整它们的宽度。
我既不想覆盖sizeThatFits()
也不想覆盖preferredLayoutAttributesFitting
据我了解,我需要做的只是确保单元格中的AutoLayout正确,然后使用属性estimatedItemSize
使单元格自动调整大小。
不幸的是,我的情况是 kinda 。 UI看起来不错,但是当我旋转设备时,我遇到了很多破损的约束。但是,当我只使用属性itemSize
并将所有单元格设置为固定大小(例如100x150)时,旋转时一切都很好,没有自动布局问题。
这就是我约束UICollectionViewCell的方式。我真的不知道为什么我必须将虚拟UIView
用作UIStackView
的“主”视图,但是Xcode在没有它的情况下对AutoLayout问题大为关注。出于测试目的,我将此视图放在单元格之外,但放在单独的UIViewController
中,以测试AutoLayout是否正常-看起来确实如此。
这是我的ViewController
的代码:
import UIKit
class ViewController: UIViewController {
@IBOutlet var myCollectionView: UICollectionView!
let items: [Item] = [
Item(title: "Cell 1"),
Item(title: "Cell 2"),
Item(title: "Cell 3"),
Item(title: "Cell 4"),
Item(title: "Cell 5"),
Item(title: "Cell 6")
]
override func viewDidLoad() {
super.viewDidLoad()
guard let layout = myCollectionView.collectionViewLayout as? UICollectionViewFlowLayout else {
fatalError("Impossibruuu - layout is not FlowLayout")
}
myCollectionView.register(UINib(nibName: "MyCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "MyCollectionViewCell")
layout.minimumInteritemSpacing = 10
layout.minimumLineSpacing = 50
// line below makes AutoLayout angry during rotations
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
// this is completely fine
//layout.itemSize = CGSize(width: 100, height: 150)
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath) as? MyCollectionViewCell else { return UICollectionViewCell() }
cell.text = items[indexPath.row].title
return cell
}
}
不幸的是,使用layout.estimatedItemSize
时,我得到了完全奇怪的日志:
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2019-06-22 18:53:18.841709+0200 CollectionViewSelfSizing[55280:2953587] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x600003d6e170 UIImageView:0x7fe820c1ac90.height == 100 (active)>",
"<NSLayoutConstraint:0x600003d6ebc0 V:[UIStackView:0x7fe820c1a020]-(0)-| (active, names: '|':UIView:0x7fe820c19e40 )>",
"<NSLayoutConstraint:0x600003d6ec60 V:|-(0)-[UIStackView:0x7fe820c1a020] (active, names: '|':UIView:0x7fe820c19e40 )>",
"<NSLayoutConstraint:0x600003d6ed00 V:[UIView:0x7fe820c19e40]-(0)-| (active, names: '|':UIView:0x7fe820c19c60 )>",
"<NSLayoutConstraint:0x600003d6eda0 V:|-(0)-[UIView:0x7fe820c19e40] (active, names: '|':UIView:0x7fe820c19c60 )>",
"<NSLayoutConstraint:0x600003d6cd70 'UISV-canvas-connection' UIStackView:0x7fe820c1a020.top == UIImageView:0x7fe820c1ac90.top (active)>",
"<NSLayoutConstraint:0x600003d6cf50 'UISV-canvas-connection' V:[UILabel:0x7fe820c1d0c0'Cell 1']-(0)-| (active, names: '|':UIStackView:0x7fe820c1a020 )>",
"<NSLayoutConstraint:0x600003d6ce60 'UISV-spacing' V:[UIImageView:0x7fe820c1ac90]-(19)-[UILabel:0x7fe820c1d0c0'Cell 1'] (active)>",
"<NSLayoutConstraint:0x600003d644b0 'UIView-Encapsulated-Layout-Height' UIView:0x7fe820c19c60.height == 50 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600003d6e170 UIImageView:0x7fe820c1ac90.height == 100 (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.