Ios UICollectionViewFlowLayout estimatedItemSize在旋转期间会打断约束,但itemSize完全可以

Ios UICollectionViewFlowLayout estimatedItemSize在旋转期间会打断约束,但itemSize完全可以,ios,swift,uicollectionview,autolayout,Ios,Swift,Uicollectionview,Autolayout,我想显示一组带有图像和标签的UICollection视图单元格,并根据标签的宽度调整它们的宽度。 我不想覆盖sizehatfits()也不想覆盖preferredlayouttributesfitting 据我所知,我需要做的只是确保单元格中的自动布局正常,然后使用propertyestimatedItemSize使单元格自动调整大小 不幸的是,对我来说,这有点像是真的。UI看起来很好,但当我旋转设备时,我有很多破坏的约束。但是,当我只使用属性itemSize并将所有单元格设置为固定大小(如10

我想显示一组带有图像和标签的UICollection视图单元格,并根据标签的宽度调整它们的宽度。 我不想覆盖
sizehatfits()
也不想覆盖
preferredlayouttributesfitting

据我所知,我需要做的只是确保单元格中的自动布局正常,然后使用property
estimatedItemSize
使单元格自动调整大小

不幸的是,对我来说,这有点像是真的。UI看起来很好,但当我旋转设备时,我有很多破坏的约束。但是,当我只使用属性
itemSize
并将所有单元格设置为固定大小(如100x150)时,在旋转过程中一切正常,没有自动布局问题

这就是我约束UICollectionViewCell的方式。我真的不知道为什么我必须使用dummy
UIView
作为
UIStackView
的“主”视图,但是没有它,Xcode会因为自动布局问题而大哭一场。出于测试目的,我将此视图放在单元格外部,但放在单独的
UIViewController
中,以测试AutoLayout是否正常-看起来是这样

我的
视图控制器的代码如下:

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.
在UIViewAlertForUnsatifiableConstraints处创建一个符号断点,以便在调试器中捕获该断点。
中列出的UIView上UIConstraintBasedLayoutDebugging类别中的方法也可能会有所帮助。
2019-06-22 18:53:18.841709+0200集合视图自调整大小[55280:2953587][布局约束]无法同时满足约束。
可能下面列表中至少有一个约束是您不想要的。
试试这个:
(1) 看看每一个约束,试着找出你不期望的;
(2) 找到添加了不需要的约束的代码,然后修复它。
(
"",
"",
"",
"",
"",
"",
"",
"",
""
)
将尝试通过打破约束进行恢复
在UIViewAlertForUnsatifiableConstraints处创建一个符号断点,以便在调试器中捕获该断点。
中列出的UIView上UIConstraintBasedLayoutDebugging类别中的方法也可能会有所帮助。

您只有两个视图,图像视图和标签,那么堆栈视图是用来做什么的呢?我想,为了减少约束的数量。也许这是一个过度,我会尝试没有堆栈视图(因此,
UIImageView
将顶部约束为0,高度==宽度==100,居中水平。
UILabel
约束为图像下方19个点,前导和尾随为0,没有底部约束。让我检查一下。堆栈视图不会减少数量约束。它们会增加数量约束!我尝试了我所说的。不仅我有在旋转过程中出现警告,但我的布局看起来很糟糕(至少之前是非常好的)。我准备认为
estimatedItemSize
+自动布局不再有效:)我不知道,我创建了疯狂的简单宠物项目来测试这一点(我的工作需要),但我认为我会坚持使用
collectionView(u:layout:sizeForestMat:)