ios - UICollectionViewCell 中的 UILabel 有时大小不正确

标签 ios swift autolayout uicollectionviewcell

我制作了一个 UI,用于使用 UICollectionView 以标记格式显示兴趣。用户从列表中选择兴趣,然后显示为 UICollectionViewCell。每个单元格都包含一个带有兴趣的 UILabel,旁边是带有“X”的 UIButton,用于删除兴趣。它大部分工作正常,但有时在添加或删除兴趣时,其中一些布局不正确,如下图所示:

Screenshot

当我打印 UILabel 的高度和宽度时,它显示它具有正确的大小(正确的宽度由绿线显示),但它的呈现就像我调用了 sizeToFit() (我在让它变大之前所做的那样) ,因为其他单元格正确显示)。这是我用来布局和调整单元格大小的代码:

class InterestsCollectionViewDelegate: NSObject, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {

    var selectedInterests: InterestsList!    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let interestLabel = UILabel()
        interestLabel.text = selectedInterests.interests[indexPath.row]
        interestLabel.sizeToFit()
        interestLabel.frame.size.width += 32
        let xButtonWidth = 20;

        let newSize = CGSize(width: interestLabel.frame.size.width + CGFloat(xButtonWidth), height: CGFloat(26))
        print("newSize for \(String(describing: interestLabel.text)): \(newSize)")
        return newSize

    }
}

class LeftAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let attributes = super.layoutAttributesForElements(in: rect)

        var leftMargin = sectionInset.left
        var maxY: CGFloat = -1.0
        attributes?.forEach { layoutAttribute in
            if layoutAttribute.frame.origin.y >= maxY {
                leftMargin = sectionInset.left
            }

            layoutAttribute.frame.origin.x = leftMargin

            leftMargin += layoutAttribute.frame.width + minimumInteritemSpacing
            maxY = max(layoutAttribute.frame.maxY , maxY)
        }

        return attributes
    }


}

有什么可能导致这种情况的想法吗?提前致谢。

编辑: 从控制台添加自动布局警告:

2018-03-28 06:43:44.474788-0700 ClikApp[6091:3425572] [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:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>",
    "<NSLayoutConstraint:0x1c0096300 V:|-(0)-[EditProfileContentView]   (active, names: EditProfileContentView:0x13bd5b420, EditProfileScrollView:0x13c08b000, '|':EditProfileScrollView:0x13c08b000 )>",
    "<NSLayoutConstraint:0x1c00968f0 V:|-(0)-[EditProfileScrollView]   (active, names: EditProfileScrollView:0x13c08b000, EditProfileSuperview:0x13bd144e0, '|':EditProfileSuperview:0x13bd144e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x1c0097de0 h=--- v=--- 'UIView-Encapsulated-Layout-Top' EditProfileSuperview.minY == 0   (active, names: EditProfileSuperview:0x13bd144e0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2018-03-28 06:43:44.497594-0700 ClikApp[6091:3425572] [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:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>",
    "<NSLayoutConstraint:0x1c0096300 V:|-(0)-[EditProfileContentView]   (active, names: EditProfileContentView:0x13bd5b420, EditProfileScrollView:0x13c08b000, '|':EditProfileScrollView:0x13c08b000 )>",
    "<NSLayoutConstraint:0x1c00968f0 V:|-(0)-[EditProfileScrollView]   (active, names: EditProfileScrollView:0x13c08b000, EditProfileSuperview:0x13bd144e0, '|':EditProfileSuperview:0x13bd144e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x1c0097de0 h=--- v=--- 'UIView-Encapsulated-Layout-Top' EditProfileSuperview.minY == 0   (active, names: EditProfileSuperview:0x13bd144e0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2018-03-28 06:43:44.519629-0700 ClikApp[6091:3425572] [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:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>",
    "<NSLayoutConstraint:0x1c0096300 V:|-(0)-[EditProfileContentView]   (active, names: EditProfileContentView:0x13bd5b420, EditProfileScrollView:0x13c08b000, '|':EditProfileScrollView:0x13c08b000 )>",
    "<NSLayoutConstraint:0x1c00968f0 V:|-(0)-[EditProfileScrollView]   (active, names: EditProfileScrollView:0x13c08b000, EditProfileSuperview:0x13bd144e0, '|':EditProfileSuperview:0x13bd144e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x1c0097de0 h=--- v=--- 'UIView-Encapsulated-Layout-Top' EditProfileSuperview.minY == 0   (active, names: EditProfileSuperview:0x13bd144e0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2018-03-28 06:43:44.535276-0700 ClikApp[6091:3425572] [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:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>",
    "<NSLayoutConstraint:0x1c0096300 V:|-(0)-[EditProfileContentView]   (active, names: EditProfileContentView:0x13bd5b420, EditProfileScrollView:0x13c08b000, '|':EditProfileScrollView:0x13c08b000 )>",
    "<NSLayoutConstraint:0x1c00968f0 V:|-(0)-[EditProfileScrollView]   (active, names: EditProfileScrollView:0x13c08b000, EditProfileSuperview:0x13bd144e0, '|':EditProfileSuperview:0x13bd144e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x1c0097de0 h=--- v=--- 'UIView-Encapsulated-Layout-Top' EditProfileSuperview.minY == 0   (active, names: EditProfileSuperview:0x13bd144e0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2018-03-28 06:43:44.550334-0700 ClikApp[6091:3425572] [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:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>",
    "<NSLayoutConstraint:0x1c0096300 V:|-(0)-[EditProfileContentView]   (active, names: EditProfileContentView:0x13bd5b420, EditProfileScrollView:0x13c08b000, '|':EditProfileScrollView:0x13c08b000 )>",
    "<NSLayoutConstraint:0x1c00968f0 V:|-(0)-[EditProfileScrollView]   (active, names: EditProfileScrollView:0x13c08b000, EditProfileSuperview:0x13bd144e0, '|':EditProfileSuperview:0x13bd144e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x1c0097de0 h=--- v=--- 'UIView-Encapsulated-Layout-Top' EditProfileSuperview.minY == 0   (active, names: EditProfileSuperview:0x13bd144e0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x1c0095c70 V:|-(8)-[UICollectionView:0x13c012400]   (active, names: EditProfileContentView:0x13bd5b420, '|':EditProfileContentView:0x13bd5b420 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

再来几张截图: Screenshot2 Screenshot3 Screenshot4

最佳答案

我想通了,我在 UILabel 上调用了一个更新函数中的 sizeToFit(),该函数在 cellForItemAt 函数中被调用。有趣的是,看起来 cellForItemAt 有时在 sizeForItemAt 之前运行,有时在之后运行。

感谢您的回复!

关于ios - UICollectionViewCell 中的 UILabel 有时大小不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49525892/

相关文章:

iphone - 带有旋转 UI 元素的 AutoLayout

ios - iOS 8 中的嵌套 Collection View 、自动布局和旋转

iOS自动布局: Can this be done with IB?

ios - 是否可以使用 Button 更改 UIPageViewController 中的当前页面?

ios - 应用程序在运行视频一段时间后进入后台模式

ios - 今天小部件应用程序启动是 'over-sensitive'

ios - 如何在 CloudKit 记录中搜索部分单词?

ios - 字符串编码 - Swift

ios - 如何在 willDisplay 单元格回调中访问 UICollectionView 中的特定单元格

ios - 连接两个相关的 TableViewController 数组