UIStackView,自动布局,表格单元格

时间:2020-01-21 01:34:45

标签: swift uitableview autolayout

我正在自定义UIStackView中创建一个带有图像和标签的UIControl,该图像和标签将位于自定义UITableViewCell中,但我的UIStackView具有高度&width为0和XCode抱怨违反约束。仅当我明确设置高度和宽度时,它才能正确显示,这是我不想要的,因为标签文本在每个单元格之间都不同。 (这都是以编程方式发生的。)

设置 在我的UITableViewCell中,我有以下内容:

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
  super.init(style: style, reuseIdentifier: reuseIdentifier)
  contentView.addSubview(control)

  NSLayoutConstraint.activate([
    control.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
    control.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
    control.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
    control.topAnchor.constraint(equalTo: contentView.topAnchor),
  ])
}

// empty coder init as well

private let control: MyControl = {
  let control: MyControl = MyControl()
  control.translatesAutoresizingMaskIntoConstraints = false
  return control
}()

MyControl中,我只有UIStackViewUIImageViewUILabel。为了不让您感到厌烦,仅... UIStackView(水平轴)使用了约束,并将其固定在四个侧面。 UIImageView(由图像启动)是一个排列的子视图,UILabel是另一个(由默认文本启动)。

如果您想查看代码:

class MyControl: UIControl {

  override init(frame: CGRect) {
    super.init(frame: frame)
    addSubview(stackView)
    stackView.addArrangedSubview(icon)
    stackView.addArrangedSubview(contentLabel)

    NSLayoutConstraint.activate([
      stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
      stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
      stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
      stackView.topAnchor.constraint(equalTo: topAnchor),
    ])
  }

// empty coder init as well

  private let contentLabel: UILabel = {
    let label: UILabel = UILabel()
    label.text = "Initial text"
    return label
  }()

  private let icon: UIImageView = {
    let iv: UIImageView = UIImageView(image: UIImage(named: "placeholder_image")!)
    iv.contentMode = .scaleAspectFit
    return iv
  }()

  private let stackView: UIStackView = {
    let stackView: UIStackView = UIStackView()
    stackView.axis = .horizontal
    stackView.translatesAutoresizingMaskIntoConstraints = false
    return control
  }()
}

我期望的是期望 UIControl为图像的高度(因为它比标签文本高),以及图像的宽度+标签文本。 (然后由于约束约束而显示完整的表格单元格宽度)。并且由于这些是在初始化这些组件时设置的,因此我希望它们具有固有的高度和宽度,以传递给UIStackView

我得到的东西 高度和宽度为零,并且XCode抱怨约束已损坏。如果删除所有约束,我不会抱怨,但是什么也不会出现(好像高度和宽度为零,但是XCode不在乎,因为我没有设置任何约束)。

我尝试过的事情 从字面上看,布局约束的每一种组合都包括在内,在所有事物上都不存在,而在所有事物上则尽可能多。我想要的 是让图像+标签文本设置UIStackView的高度和宽度,然后设置UIControl的高度和宽度,这将然后在UITableViewCell中设置高度(我知道我的宽度为100%-稍后会更改)。

其他注意事项 除了在我的实际代码中,我在UITableViewCell上方有一个多行标签,我的MyControl并没有其他会引起任何问题的特殊之处,它应该(并且确实)导致我的UITableViewCell扩大高度。

1 个答案:

答案 0 :(得分:0)

您的问题的问题在于,您显示的太多代码是虚假的,很难猜测您可能实际上在做什么。您声称在您的表格视图单元格中(我认为这是表格视图单元格的子类),您在说

override init(frame: CGRect) {
    super.init(frame: frame)

但这将永远不会编译,因为init(frame:)不是UITableViewCell的指定初始化程序。您有这样的代码:

private let contentLabel: UILabel = {
    let label: UILabel = UILabel()
    label.text = "Initial text"
    return label
}

但是,由于函数不是标签,因此永远不会编译。

如果我们对所有这些都留有余地并修复您的代码,那么很难看出您会做错什么。我更正了您的代码,使其可以编译,并在表格视图中得到了它:

enter image description here

这可能不完全是您想要的,但是图像视图肯定会将单元格调整到自己的高度。

您所做的根本不是一个如何构造和配置表格视图单元格(您应该在cellForRowAt中进行工作,而不是在单元格的初始化程序中对单元格的图像视图和标签内容进行硬编码),但是根据您所显示的内容,图像视图的大小确实会调整堆栈视图的大小,而堆栈视图的大小也会确定单元格的大小(与我自己的最初期望相反)。

另一个问题是,如果不解决哪个应该占主导地位的歧义,就不能将图像视图和标签置于自动布局的情况。我添加以下行来做到这一点:

    iv.setContentHuggingPriority(.defaultLow+1, for: .horizontal)