Я вижу разные примеры, когда устанавливаются ограничения. Некоторые устанавливают их в viewDidLoad
/ loadView
(после добавления подпредставления). Другие устанавливают их в методе updateViewConstraints
, который вызывается viewDidAppear
.
Когда я пытаюсь установить ограничения, updateViewContraints
может возникнуть скачок в макете, например небольшая задержка перед появлением представления. Кроме того , если я использую этот метод, я должен очистить существующие ограничения первого т.е. [self.view [removeConstraints:self.view.constraints]
?
ios
cocoa-touch
autolayout
Гейзенберг
источник
источник
updateViewConstraints
: Вы можете переопределить этот метод в подклассе, чтобы добавить ограничения к представлению или его подпредставлениям. (из документации Apple )Ответы:
Я установил свои ограничения в
viewDidLoad
/loadView
(я нацелен на iOS> = 6).updateViewConstraints
полезен для изменения значений ограничений, например, если какое-то ограничение зависит от ориентации экрана (я знаю, это плохая практика), вы можете изменить егоconstant
в этом методе.Добавление ограничений
viewDidLoad
показано во время сеанса «Введение в автоматический макет для iOS и OS X» (WWDC 2012), начиная с 39:22. Я думаю, что это одна из тех вещей, о которых говорят на лекциях, но не отражаются в документации.ОБНОВЛЕНИЕ: я заметил упоминание о настройке ограничений в управлении ресурсами в контроллерах представления :
UPDATE 2 : Во время WWDC 2015 Apple , дал новое объяснение о
updateConstraints
иupdateViewConstraints
рекомендуемое использование:источник
@"|-[button1]-[button2]-|"
в ViewController, верно? Или есть другой способ?updateViewConstraints
?Я рекомендую создать BOOL и установить их в
-updateConstraints
UIView (или-updateViewConstraints
для UIViewController).-[UIView updateConstraints]
: (яблочные документы)Оба
-updateConstraints
и-updateViewConstraints
могут вызываться несколько раз в течение жизни представления. (ВызовsetNeedsUpdateConstraints
представления вызовет это, например.) В результате вам необходимо убедиться, что вы не создали и не активировали повторяющиеся ограничения - либо с помощью BOOL, чтобы выполнить настройку определенных ограничений только один раз, либо убедившись, что для деактивации / удаления существующих ограничений перед созданием и активацией новых.Например:
- (void)updateConstraints { // for view controllers, use -updateViewConstraints if (!_hasLoadedConstraints) { _hasLoadedConstraints = YES; // create your constraints } [super updateConstraints]; }
Приветствую @fresidue в комментариях за указание на то, что в документации Apple рекомендуется позвонить
super
в качестве последнего шага. Если вы позвонитеsuper
перед внесением изменений в некоторые ограничения, вы можете столкнуться с исключительной ситуацией во время выполнения (аварийным завершением).источник
-updateConstraints
или чему-то еще - она все равно будет вызвана, а вы все равно будете звонить[super updateConstraints]
.super
в самом конце вашей реализации-updateConstraints
или-updateViewConstraints
. См. Этот комментарий для получения дополнительной информации.Это должно быть сделано в ViewDidLoad, согласно видео WWDC от Apple и документации.
Понятия не имею, почему люди рекомендуют updateConstraints. Если вы это сделаете в updateConstraints, вы столкнетесь с проблемами с NSAutoresizingMaskLayoutConstraint с автоматическим изменением размера, потому что ваши представления уже приняли во внимание автоматические маски. Вам нужно будет удалить их в updateConstraints, чтобы заставить работать.
UpdateConstraints должен быть именно для этого, когда вам нужно «обновить» их, внести изменения и т. Д. Из начальной настройки.
источник
Сделайте это в виду, сделал ли метод подвидов макета
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() }
источник
У меня есть решение для изменения ограничений до загрузки тех, кто находится в раскадровке. Это решение устраняет любые задержки после загрузки представления.
-(void)updateViewConstraints{ dispatch_async(dispatch_get_main_queue(), ^{ //Modify here your Constraint -> Activate the new constraint and deactivate the old one self.yourContraintA.active = true; self.yourContraintB.active= false; //ecc.. }); [super updateViewConstraints]; // This must be the last thing that you do here -> if! ->Crash! }
источник
Вы можете установить их в viewWillLayoutSubviews: тоже:
override func viewWillLayoutSubviews() { if(!wasViewLoaded){ wasViewLoaded = true //update constraint //also maybe add a subview } }
источник
Это сработало для меня:
Swift 4.2
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Modify your constraints in here ... }
Хотя, честно говоря, не уверен, стоит ли оно того. Кажется, он загружается немного медленнее, чем в viewDidLoad (). Я просто хотел убрать их из последнего, потому что он становится массовым.
источник
Следующий пример - передать любое представление другому классу. создать мое представление из раскадровки
Swift 5.0
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) DispatchQueue.main.async { self.abcInstance = ABC(frame: self.myView.frame) } }
источник