SnapKit 和 Dynamic UITableViewCell 布局不正确

Posted

技术标签:

【中文标题】SnapKit 和 Dynamic UITableViewCell 布局不正确【英文标题】:SnapKit and Dynamic UITableViewCell not being laid out correctly 【发布时间】:2018-10-12 14:10:21 【问题描述】:

我目前正在构建一个可重复使用的视图,该视图利用了 UITableView 为其单元格提供的动态调整大小。

我想要实现的是在单元格中为视图提供宽度和高度,具体取决于它在结构中定义的 size 属性中给出的大小,我使用配置函数通过它, 设置好视图大小后。

然后我将它集中在 xAxis 上,并使用结构中的一个属性在视图周围应用任何边距,该属性只是一个 UIEdgeInset 属性。使用 SnapKit 库看起来像这样。

    if  let formImageItem = formImageItem,
        let size = formImageItem.size 

        formItemImgVw = UIImageView(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        formItemImgVw?.image = formImageItem.image
        formItemImgVw?.contentMode = formImageItem.aspectFit

        contentView.addSubview(formItemImgVw!)

        formItemImgVw?.snp.makeConstraints( (make) in
              make.size.equalTo(CGSize(width: size.width, height: size.height))
              make.top.equalTo(formImageItem.margin.top)
              make.bottom.equalTo(formImageItem.margin.bottom)
              make.centerX.equalToSuperview()
        )
    

我似乎遇到的问题是我收到以下警告。

2018-10-12 14:57:34.101532+0100 xxxx Dev[6104:2160548] [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. 
(
    "<SnapKit.LayoutConstraint:0x2830ec720@FormImageViewTableViewCell.swift#61 UIImageView:0x10530a940.height == 114.0>",
    "<SnapKit.LayoutConstraint:0x2830ec780@FormImageViewTableViewCell.swift#62 UIImageView:0x10530a940.top == UITableViewCellContentView:0x105503500.top>",
    "<SnapKit.LayoutConstraint:0x2830ec7e0@FormImageViewTableViewCell.swift#63 UIImageView:0x10530a940.bottom == UITableViewCellContentView:0x105503500.bottom>",
    "<NSLayoutConstraint:0x2837e2580 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x105503500.height == 44   (active)>"
)

Will attempt to recover by breaking constraint 
<SnapKit.LayoutConstraint:0x2830ec720@FormImageViewTableViewCell.swift#61 UIImageView:0x10530a940.height == 114.0>

我明白这基本上告诉我它选择使用默认为表格视图单元格设置的高度 44。但我似乎无法理解为什么它使用这个默认高度,而不是我在约束中定义的高度,并将高度应用于视图,同时还将间距添加到顶部和底部。

此外,当使用调试器检查 UI 时,似乎根本没有设置高度,您可以看到 44 的高度只是剪裁了整个图像视图。

所以最终我想要实现的是能够为视图提供定义的高度和宽度,并使用值来应用顶部和底部间距(边距)以调整其当前所在的单元格的大小。

【问题讨论】:

查看 SnapKit 的文档,您似乎希望您的顶部和底部约束为:make.top.equalTo(contentView.snp.top).offset(formImageItem.margin.top)make.bottom.equalTo(contentView.snp.bottom).offset(formImageItem.margin.bottom)?我假设formImageItem.margin.top 是一个数值?而且,请记住,底部值可能需要为负数...... @DonMag 所以刚刚尝试过,似乎内容视图正在强制执行 44 的高度,这覆盖了我正在设置的高度...... 我认为您需要仔细检查您的代码,并仔细检查(调试)您在 formImageItem 对象中获得的所有值。我刚刚下载了 SnapKit 并使用您的 formItemImgVw?.snp.makeConstraints() 块进行了快速表格视图,得到了以下结果:imgur.com/a/qkvY9FP ...没有自动布局错误或警告,并且单元格按预期调整大小。 @DonMag Dunno 为什么但是在重置到最后一次提交并从下面接受的答案中添加属性之后一切正常,所以在我的代码中的某个地方我一定是设置了错误的属性 【参考方案1】:

你需要降低底部约束的优先级所以替换这个

make.bottom.equalTo(formImageItem.margin.bottom)

make.bottom.equalTo(formImageItem.margin.bottom).priority(999)

加在viewDidLoad

tableView.estimatedRowHeight = 120 
tableView.rowHeight = UITableViewAutomaticDimension

abd 不要实现heightForRowAt

【讨论】:

已经试过了,和顶部一样我仍然没有得到想要的效果,因为没有底部约束,tableviewcell 高度不会改变。 那么为什么是 120?关于估计的行高和行高? 在计算 log 114 中的真实高度之前,您需要给出估计高度以帮助绘图中的自动布局

以上是关于SnapKit 和 Dynamic UITableViewCell 布局不正确的主要内容,如果未能解决你的问题,请参考以下文章

Snapkit 和 TableView 中的多个自定义单元格

读 SnapKit 和 Masonry 自动布局框架源码(轉)

如何在 Objc 项目中使用 SnapKit?

定义 SnapKit 值时,CGAffineTransform 旋转会导致宽度和高度之间的切换

Snapkit 和 UILabel 的轮换

无法将模块“Snapkit”加载为“Snapkit”