it-swarm.com.ru

Пользовательский вид - self.frame не правильно?

Так что у меня есть пользовательский класс UIView

class MessageBox: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        createSubViews()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        createSubViews()
    }
    func createSubViews() {

        let testView = UIView(frame: self.frame)
        testView.backgroundColor = UIColor.brown
        self.addSubview(testView)
    }
}

Я добавил UIView внутри раскадровки и дал ему некоторые ограничения:

100 сверху (суперпредставление), 0 слева и справа, высота 180

Но когда я запускаю приложение, коричневое подпредставление, которое я создал в коде, становится большим. Я напечатал self.frame в моем собственном представлении, и оказалось, что кадр (0,0,1000,1000). Но почему? Я установил ограничения, это должно быть что-то вроде (0,0,deviceWith, 180).

 enter image description here

Что я сделал не так?

Правка: Это моя установка раскадровки:

 enter image description here

7
Quantm

Краткий и простой ответ:

Ты делаешь это слишком рано.


Подробный ответ:

Когда представление инициализируется из файла Interface Builder (xib или раскадровка), его фрейм первоначально устанавливается на фрейм, который он имеет в Interface Builder. Вы можете посмотреть на это как на временный заполнитель.

При использовании Auto Layout ограничения разрешаются (= фактический кадр представления вычисляется) внутри метода представления layoutSubviews().

Таким образом, есть два возможных решения вашей проблемы:

  1. (предпочтительно) Если вы используете автоматическую компоновку, используйте ее во всем виде.

    • Или добавьте свой testView в Интерфейсный Разработчик также и создайте выход для него
    • или создайте свой testView в коде, как вы делаете, затем установите для его свойства translatesAutoResizingMaskIntoConstraints значение false (для сортировки «активировать автоматическое расположение») и добавьте в него необходимые ограничения в коде.
  2. Установите фрейм testView после того, как сам механизм фрейма установил фрейм представления MessageBox. Единственное место, где вы можете быть уверены, что система разрешила кадр представления из ограничений, - это когда вызывается layoutSubviews().

    override func layoutSubviews() {
        super.layoutSubviews()
        testView.frame = self.frame
    }
    

    (Конечно, вам нужно объявить вашу testView как свойство/глобальную переменную.)

17
Mischa
override func layoutSubviews() {
    super.layoutSubviews()
    testView.frame = self.frame
}

это также работает, когда вы добавляете пользовательский класс в UIView в раскадровке, который использует autolayout . спасибо Миша !

1
Murphy

Попробуйте использовать якоря для вашего зрения: 

MessageBox.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor).active
= true 
MessageBox.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor).active
= true 
MessageBox.widthAnchor.constraintEqualToConstant(150).active = true 
MessageBox.heightAnchor.constraintEqualToConstant(100).active = true

Этот метод должен использоваться внутри вашего класса

1
Carlo

попробуйте добавить ограничение высоты и ширины относительно высоты суперпредставления с некоторым множителем.

0
Dasem