Получите фактическую ширину подвида во время выполнения (Swift 4)

Xcode предоставляет сегментированный элемент управления, но мне нужен настраиваемый сегментированный элемент управления с селектором, который перемещается к каждой кнопке при нажатии. Я использую для этого 3 представления. Одним из них является «основной» вид, к которому я добавил два подвида. Одно из подпредставлений — это селектор (UIView), а другое — это UIStackView, который содержит кнопки. Я использую selector = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.width/CGFloat(buttons.count), height: self.frame.height)) для размера селектора. Когда я использую свой класс для представления в раскадровке, все выглядит нормально. Я установил ограничения для суперпредставления, но когда я запускаю приложение с помощью симулятора, я получаю ширину, установленную в раскадровке, а не фактическую ширину во время выполнения с помощью self.frame.width.

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


person nasxlf    schedule 29.10.2017    source источник


Ответы (2)


UIControl наследуется от класса UIView, который можно использовать с помощью функции layoutSubviews для получения правильного Frame после применения ограничений.

override func layoutSubviews() {
     super.layoutSubviews()
    //self.frame will be correct here
}

использованная литература:

https://developer.apple.com/documentation/uikit/uiview/1622482-layoutsubviews https://developer.apple.com/documentation/uikit/uicontrol

person Kassem Itani    schedule 29.10.2017
comment
Спасибо, это выручает меня! Кроме того, layoutSubviews() вызывается, когда телефон поворачивается, поэтому он автоматически регулирует ширину. Знаете ли вы, вызывается ли этот метод, когда вы вносите некоторые коррективы в раскадровку? Потому что он также изменяет ширину селектора, когда я изменяю размер представления. - person nasxlf; 30.10.2017
comment
Итак, у меня это сработало, но через день каждый раз, когда я выбираю класс моего костюма в инспекторе идентификации, Xcode 9 зависает. Когда я удаляю функцию layoutSubviews, она не зависает. - person nasxlf; 31.10.2017
comment
Убедитесь, что у вас есть слово «переопределить» перед функцией переопределения func layoutSubviews() и убедитесь, что вы вызываете super.layoutSubviews() - person Kassem Itani; 01.11.2017
comment
Я написал «переопределить» перед функцией и вызвал super.layoutSubviews(). все еще холодно - person nasxlf; 01.11.2017
comment
ОБНОВЛЕНИЕ - когда я сначала добавляю ограничения в представление, а затем добавляю метод, Xcode не зависает. Но когда я впервые добавляю метод в свой код без ограничений, Xcode зависает. Кто-нибудь знает, почему? - person nasxlf; 01.11.2017
comment
Вчера я использовал версию 9.0, а сегодня обновил ее до версии 9.1. Обе версии имеют одну и ту же проблему. Я сообщу об этом! - person nasxlf; 01.11.2017

Похоже, вы получаете кадр до того, как установлены ограничения, попробуйте получить событие кадра viewDidLayoutSubviews или viewDidAppear

ниже приведены события и статус ограничений:

  • viewDidLoad -- ограничения не установлены
  • viewWillAppear -- ограничения не установлены
  • viewWillLayoutSubviews -- Устанавливаются ограничения
  • viewDidLayoutSubviews -- установлены ограничения
  • viewDidAppear -- установлены ограничения
person Kassem Itani    schedule 29.10.2017
comment
Я не могу этого сделать, потому что мой класс UICostumSegmentedController наследуется от UIControl, а не от UIViewController, а значит, у него нет этих функций - person nasxlf; 29.10.2017