Автозапуск в UITextField: автоматический макет еще требуется после выполнения -layoutSubviews
Я подклассифицирую UITextField, чтобы добавить ярлык с левой стороны. Я использую автозапуск для компоновки ярлыка. Тем не менее, я продолжаю получать этот сбой:
Вот как я делаю свой код макета:
- (void)updateConstraints {
self.segmentLabel.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *constraint;
constraint = [NSLayoutConstraint constraintWithItem:self.segmentLabel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0f];
[self addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:self.segmentLabel attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0f];
[self addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:self.segmentLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0f];
[self addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:self.segmentLabel attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:self.segmentWidth];
[self addConstraint:constraint];
[super updateConstraints];
}
Когда я не вношу никаких изменений в текстовое поле, это отлично работает.
Однако, если я попытаюсь установить текст заполнителя, я получаю это исключение:
Завершение приложения из-за неперехваченного исключения "NSInternalInconsistencyException", причина: "Автоматическая компоновка по-прежнему требуется после выполнения -layoutSubviews. Реализация DDSegmentedTextField для -layoutSubviews требует вызова super. '
Однако я не переопределяю -layoutSubviews.
Кто-нибудь сталкивался с этим? Что я делаю неправильно?
Спасибо!
Ответы
Ответ 1
Итак, я столкнулся с этой же ошибкой несколько дней назад. Оказывается, я пытался разбить субвью внутри моего подкласса UITextfield
, установив на них свойства, перемещая их и т.д., Но никогда не указывал явному представлению (т.е. Вызывал [self layoutIfNeeded]
).
iOS 8, по-видимому, заставляет взглянуть на макет всех своих подзонов, а затем настраивает ограничения на него. iOS 7 не будет, и вам нужно явно указывать представления для перерисовки своих подзонов при изменении, если вы используете автозапуск.
В моем случае я подклассифицировал UITextfield
и добавил ярлык в сторону. Я настроил фрейм метки, добавив ограничения в поле UIText. Одним из общедоступных методов, которые я мог бы назвать в моем классе, был
- (void)setLabelText:(NSString *)newText{
self.sideLabel.text = newText;
}
Это вызвало сбой моего приложения, когда появился контроллер представления, содержащий мое текстовое поле с подклассом. Добавив layoutIfNeeded
, все теперь отлично работает в iOS7 и iOS8.
- (void)setLabelText:(NSString *)newText{
self.sideLabel.text = newText;
[self layoutIfNeeded];
}
Это нужно вызывать каждый раз, когда вы изменяете часть представления в своем подклассе. Это включает настройку, когда вы добавляете subviews, когда вы меняете свойства вида, что-либо действительно. Перед тем, как функция, которая изменит ваше представление, вернется, вызовите layoutIfNeeded
в своем представлении. Это похоже на несколько стандартных элементов управления пользовательского интерфейса, включая UITextfield, UITableView и UICollectionView, хотя я уверен, что есть и другие. Я надеюсь, что это было достаточно ясно и помогло решить вашу проблему.
Ошибка, которую вы получаете, не очень полезна и даже не применима в моем случае. Хотя я получал точно такую же ошибку, ни один из моих представлений не реализовал layoutSubviews
, и поэтому все они использовали метод [super layoutSubviews]
.
Ответ 2
Эта проблема появляется в iOS < 8
При создании подкласса UIView и добавлении представлений мы можем поручить элементу управления построить и автозапуск сначала подвью.
Используйте этот оператор, когда пользовательский интерфейс необходимо обновить:
[self layoutIfNeeded];
iOS 8+ отлично справляются с проблемой, если они есть внутри.
Ответ 3
У меня была такая же проблема. Это может быть вызвано неправильными ограничениями, может быть, некоторым набором в Storyboard. Попробуйте удалить некоторые из них и посмотрите, работает ли это, чтобы выяснить, что неправильно