Как сделать так, чтобы autolayout работал с пользовательским UIView на XIB? - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть UIView на XIB, содержащий UIImageView и UILabel с небольшим пробелом между ними.Горизонтальный макет представляет собой простую цепочку |--image--label--|, в которой -- - это некоторое фиксированное пространство.Высота установлена ​​равной 40, это представление горизонтально центрировано в контроллере вида и имеет ограничение ширины >= 100.

Если я изменю текст метки, ширина моего составного представления обновится, как ожидаетсяwidth - измененная ширина его метки, и он остается точно по центру на контроллере вида.

Поскольку мне нужен UIView, содержащий изображение и метку, в других местах я создал собственный класс, состоящий изфайла XIB и Swift.Давайте назовем это ItemView.

У меня проблема в том, что пустой UIView на моем контроллере представления XIB, класс которого я изменил на ItemView, больше не принимает ограничение ширины >= 40,Это, конечно, потому что контроллер представления XIB больше не видит переменную ширину UILabel, а вместо этого просто обычный UIView класса ItemView.Я получаю сообщение об ошибке «Неравенство с неоднозначностью».

В результате ширина моего пользовательского представления остается равной 40. Это работает немного, если я укажу большую> = ширину метки;тогда текст обрезается только при достижении этой ширины.Но во втором случае мой пользовательский вид больше не центрируется по горизонтали, а смещен немного влево.

Как мне решить эту проблему?Или, как я могу сказать IB, чтобы он обрабатывал мой пользовательский ItemView так же, как UILabel?

В моем ItemView я сделал все, что мог найти:

override class var requiresConstraintBasedLayout: Bool
{
    return true
}

Позвоните setNeedsLayout() после установки текста метки.

Позвоните myLabel.translatesAutoresizingMaskIntoConstraints = false.

Позвоните self.translatesAutoresizingMaskIntoConstraints = false.

И позвоните self.setNeedsUpdateConstraints() в обоих init() s.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Как я структурировал свой пользовательский UIView: Владелец файлов моего XIB - ItemView.ItemView имеет @IBOutlet var: UIView!, который связан с представлением в XIB.Тогда у меня есть:

init()
{
    super.init(frame: .zero)

    self.initView()
}

required init?(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder)

    self.initView()
}

private func initView()
{
    Bundle.main.loadNibNamed("ItemView", owner: self, options: nil)
    self.view.frame = CGRect(x: 0.0, y: 0.0, width: self.width, height: self.height)
    self.addSubview(self.view!)
}

(мне кажется, что этот дополнительный UIView необходим при создании пользовательского UIView с XIB. Хотелось бы услышать, если он вообще не нужен.)

Чтобы это работало, мне нужно было позвонить self.invalidateIntrinsicContentSize() после обновления метки.И переопределить intrinsicContentSize:

override open var intrinsicContentSize: CGSize
{
    return self.view.systemLayoutSizeFitting(self.bounds.size)
}

Обратите внимание, что я звоню это на self.view, а не на self.

Спасибо @matt за то, что указал мне правильное направление.Впервые я столкнулся с чем-то подобным.

Следующие вещи, которые я попробовал, нам всем не нужны:

override class var requiresConstraintBasedLayout: Bool
{
    return true
}

Позвоните setNeedsLayout() после установки текста метки.

Звоните myLabel.translatesAutoresizingMaskIntoConstraints = false.

Звоните self.translatesAutoresizingMaskIntoConstraints = false.

И звоните self.setNeedsUpdateConstraints() в обоих init() с.

0 голосов
/ 20 декабря 2018

Настройте это всплывающее окно в Инспекторе размеров представления:

enter image description here

Теперь IB не будет беспокоиться о ваших спецификациях размера.Вы знаете лучше, чем IB, и это то, как сообщить IB этот факт.


Другой способ: настроить это всплывающее окно в инспекторе размера представления:

enter image description here

Это сообщает IB, что представление будет иметь внутренний размер контента, о котором он не знает.


Любой из них будетРабота.Как вы можете видеть на этом скриншоте, я дал своему пользовательскому виду ограничение ширины больше или равно 40, но IB не жалуется на какую-либо ошибку:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...