Ios 如何为具有动态高度的表格单元正确设置自动布局?

Ios 如何为具有动态高度的表格单元正确设置自动布局?,ios,swift,uitableview,Ios,Swift,Uitableview,我尝试创建UITableViewCell并设置子视图,如下所示: class MyCellView: UITableViewCell { private let ImageView = UIImageView() private let titleView = UILabel() override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(styl

我尝试创建UITableViewCell并设置子视图,如下所示:

class MyCellView: UITableViewCell {

    private let ImageView = UIImageView()
    private let titleView = UILabel()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {

        super.init(style: style, reuseIdentifier: reuseIdentifier)

        contentView.addSubview(ImageView)
        contentView.addSubview(titleView)

        ImageView.translatesAutoresizingMaskIntoConstraints = false
        ImageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        ImageView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
        ImageView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
        ImageView.heightAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.6).isActive = true

        titleView.translatesAutoresizingMaskIntoConstraints = false
        titleView.topAnchor.constraint(equalTo: ImageView.bottomAnchor).isActive = true
        titleView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
        titleView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
        titleView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true

        titleView.numberOfLines = 0

        titleView.text = " "   // <-- *** please note this line

    }
}
我的问题是,如果我没有在单元格中设置标题视图的文本,例如如果我在单元格视图中备注最后一行:

// titleView.text = " "
我将从XCode获取约束错误。但是如果我设置了文本,一切都正常

文本是从Internet动态下载的,因此文本可能为空。此外,我可以将文本设置为一个空白,我想知道我是否误解了这里的任何内容?如果我改正了什么,文本可以是空的还是零

类似地,如果我完全删除titleView的代码,我只想在单元格中有一个UIImageView,我发现单元格的高度没有展开。如何设置它,以便我可以在单元格中获得动态高度的图像

编辑:约束错误:

2017-12-22 15:35:34.715865+0800 MyProject[15774:733515] [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:0x60c000095450 V:|-(0)-[UIImageView:0x7ff40df0de90]   (active, names: '|':UITableViewCellContentView:0x7ff40df0edc0 )>",
"<NSLayoutConstraint:0x60c0000955e0 UIImageView:0x7ff40df0de90.height == 0.6*UITableViewCellContentView:0x7ff40df0edc0.width   (active)>",
"<NSLayoutConstraint:0x60c000095630 V:[UIImageView:0x7ff40df0de90]-(0)-[UILabel:0x7ff40df0e0c0]   (active)>",
"<NSLayoutConstraint:0x60c0000957c0 UILabel:0x7ff40df0e0c0.bottom == UITableViewCellContentView:0x7ff40df0edc0.bottom   (active)>",
"<NSLayoutConstraint:0x60c000096210 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7ff40df0edc0.height == 248.333   (active)>",
"<NSLayoutConstraint:0x60c000095ea0 'UIView-Encapsulated-Layout-Width' UITableViewCellContentView:0x7ff40df0edc0.width == 414   (active)>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x60c000095630 V:[UIImageView:0x7ff40df0de90]-(0)-[UILabel:0x7ff40df0e0c0]   (active)>

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.
如果要避免警告,请尝试下面的代码

class MyCellView: UITableViewCell {

  private let ImageView = UIImageView()
  private let titleView = UILabel()

  override init(style: UITableViewCellStyle, reuseIdentifier: String?) {

    super.init(style: style, reuseIdentifier: reuseIdentifier)

    contentView.addSubview(ImageView)
    contentView.addSubview(titleView)

    ImageView.translatesAutoresizingMaskIntoConstraints = false
    ImageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    ImageView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
    ImageView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
    let heightConstraint = ImageView.heightAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.6)
    heightConstraint.priority = UILayoutPriority.defaultLow
    heightConstraint.isActive = true

    titleView.translatesAutoresizingMaskIntoConstraints = false
    titleView.topAnchor.constraint(equalTo: ImageView.bottomAnchor).isActive = true
    titleView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
    titleView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
    titleView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true

    titleView.numberOfLines = 0

//    titleView.text = " "
  }
}
如果您完全删除了关于titleView的代码,并且希望在单元格中具有动态高度的UIImageView,请为imageView添加bottomAnchor约束

如果要避免警告,请尝试下面的代码

class MyCellView: UITableViewCell {

  private let ImageView = UIImageView()
  private let titleView = UILabel()

  override init(style: UITableViewCellStyle, reuseIdentifier: String?) {

    super.init(style: style, reuseIdentifier: reuseIdentifier)

    contentView.addSubview(ImageView)
    contentView.addSubview(titleView)

    ImageView.translatesAutoresizingMaskIntoConstraints = false
    ImageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    ImageView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
    ImageView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
    let heightConstraint = ImageView.heightAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.6)
    heightConstraint.priority = UILayoutPriority.defaultLow
    heightConstraint.isActive = true

    titleView.translatesAutoresizingMaskIntoConstraints = false
    titleView.topAnchor.constraint(equalTo: ImageView.bottomAnchor).isActive = true
    titleView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
    titleView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
    titleView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true

    titleView.numberOfLines = 0

//    titleView.text = " "
  }
}
如果您完全删除了关于titleView的代码,并且希望在单元格中具有动态高度的UIImageView,请为imageView添加bottomAnchor约束


这似乎是一个已知错误的结果-tableView设置的高度与autolayout计算的高度发生冲突。渲染单元时,tableView首先应用默认高度,计算自动布局高度,然后使用后者-至少看起来是这样。看我的

这意味着,您使用的约束是可以的,至少在我看来是这样。只需将定义高度的一个约束设置为priority=999,这样,在禁用默认高度约束之前,不会导致任何冲突。最终,它将导致使用您的约束,因此不会造成任何麻烦

注意:注意imageView高度限制:

ImageView.heightAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.6).isActive = true

如果您想省略图像,从而以高度=0的方式渲染它,这将再次给您带来麻烦,只需降低优先级就可以达到您想要的效果。如果图像始终存在,则无需考虑我的P.S.:。

这似乎是一个已知错误的结果-tableView设置的高度与autolayout计算的高度发生冲突。渲染单元时,tableView首先应用默认高度,计算自动布局高度,然后使用后者-至少看起来是这样。看我的

这意味着,您使用的约束是可以的,至少在我看来是这样。只需将定义高度的一个约束设置为priority=999,这样,在禁用默认高度约束之前,不会导致任何冲突。最终,它将导致使用您的约束,因此不会造成任何麻烦

注意:注意imageView高度限制:

ImageView.heightAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.6).isActive = true

如果您想省略图像,从而以高度=0的方式渲染它,这将再次给您带来麻烦,只需降低优先级就可以达到您想要的效果。如果图像始终存在,那么请不要介意我的P.S.:。

约束错误是什么?@MilanNosáľ已更新。约束错误是什么?@MilanNosáľ已更新。我按照您的建议添加了代码行,仍然存在约束警告。@JoeHuang我已更新了我的答案,您可以再次检查。我按照您的建议添加了代码行,仍然有约束警告。@JoeHuang我已经更新了我的答案,您可以再次检查。