UICollectionViewCell 中的 UILabel 有时无法正确调整大小
Posted
技术标签:
【中文标题】UICollectionViewCell 中的 UILabel 有时无法正确调整大小【英文标题】:UILabel within UICollectionViewCell sometimes not sizing properly 【发布时间】:2018-03-28 04:02:48 【问题描述】:我使用 UICollectionView 制作了一个用于以标签格式显示兴趣的 UI。用户从列表中选择兴趣,然后将其显示为 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.
更多截图:
【问题讨论】:
你是否在情节提要中设置约束? 是的,标签和按钮被限制在单元格的边缘,并且 label.trailingedge == button.leadingedge,按钮的宽度是固定的。 很难说究竟是什么原因造成的,但也许要问一下损坏的有什么不同?我认为它是不同的,因为它是排中的第三个,尝试创造另一种情况,你连续有 3 个,看看它是否也被损坏了。这可能会帮助您缩小范围并找到问题 谢谢@Eyzuky。我一直找不到模式,有时会在我添加项目时发生,有时在我删除项目时会发生,并且无论订单或行号如何都会发生。我正在尝试修复控制台上一些看似无关的自动布局警告(现在尝试学习视觉格式语言)。这对您来说是自动布局问题还是其他问题? 你能再发 2-3 张截图吗?您还可以添加在控制台中收到的警告 【参考方案1】:我想通了,我在 UILabel 上调用 sizeToFit() 的更新函数是在 cellForItemAt 函数内部调用的。有趣的是,看起来 cellForItemAt 有时在 sizeForItemAt 之前运行,有时在之后。
感谢您的回复!
【讨论】:
以上是关于UICollectionViewCell 中的 UILabel 有时无法正确调整大小的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 UIButton 删除 UICollectionViewCell
无法使用 UICollectionVIewCell 数据加载 UIView
UICollectionViewCell 中的 Outlet 为零
UICollectionViewCell 中的 SwiftUI 视图