UIStackView, Autolayout, Table Cells - PullRequest
       3

UIStackView, Autolayout, Table Cells

0 голосов
/ 21 января 2020

Я создаю UIStackView с изображением и меткой в ​​пользовательском UIControl, который будет в пользовательском UITableViewCell, за исключением того, что мой UIStackView имеет высоту и ширину 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, я просто есть UIStackView, UIImageView и UILabel. Чтобы не утомлять вас кодом ... только 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 высоту изображения (потому что оно выше текста метки) и ширину изображения + текст метки. (И затем отобразить полную ширину ячейки таблицы из-за этого закрепления ограничения). И поскольку они устанавливаются при инициализации этих компонентов, я ожидаю, что они будут иметь высоту и ширину c для передачи в UIStackView.

Что я получаю Высота и ширина ноль, и жалобы XCode о нарушении ограничений. Если я удаляю все ограничения, я не получаю жалоб, но ничего не появляется (как будто высота и ширина равны нулю, но XCode не волнует, потому что я не установил никаких ограничений).

What I ' ve Попробовал Буквально каждая комбинация ограничений макета, в том числе ни одна на все и столько, сколько я могу на все. То, что я хотел бы , так это чтобы текст image + label устанавливал высоту и ширину UIStackView, который затем устанавливал бы высоту и ширину UIControl, который затем устанавливал бы высоту в UITableViewCell (я знаю, что у меня ширина 100% - это изменится позже).

Другие соображения В моем UITableViewCell нет ничего особенного, что могло бы вызвать какие-либо проблемы, кроме этого в моем реальном коде у меня есть многострочная метка выше MyControl, которая должна (и делает) заставлять мой UITableViewCell увеличиваться в высоте.

1 Ответ

0 голосов
/ 21 января 2020

Проблема с вашим вопросом состоит в том, что большая часть кода, который вы показали, является поддельной, что трудно догадаться, что вы на самом деле делаете. Вы утверждаете, что в своей ячейке табличного представления (я предполагаю, что это подкласс ячейки табличного представления) вы говорите

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...