Autolayout en UITextField: Auto Layout aún es necesario después de ejecutar -layoutSubviews

Estoy subclassando UITextField para agregar una label en el lado izquierdo. Estoy usando la reproducción automática para diseñar la label. Sin embargo, sigo recibiendo este crash:

Así es como estoy haciendo mi código de layout:

- (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]; 

}

Cuando no hago ningún ajuste al campo de text, esto funciona bien.

Sin embargo, si trato de establecer el text del marcador de position, obtendré esta exception:

Finalización de la aplicación debido a la exception no detectada 'NSInternalInconsistencyException', motivo: 'El layout automático sigue siendo necesario después de ejecutar -layoutSubviews. La implementación de DDSegmentedTextField de -layoutSubviews necesita llamar super. '

Sin embargo, no estoy sobrescribiendo -layoutSubviews.

¿Alguien ha encontrado esto? ¿Qué estoy haciendo mal?

¡Gracias!

Así que me encontré con este mismo error hace unos días también. Resulta que estaba tratando de distribuir subprocesss dentro de mi subclass UITextfield , estableciendo properties en ellos, moviéndolos, etc., pero nunca le [self layoutIfNeeded] explícitamente a la vista que se expusiera (es decir, llamando [self layoutIfNeeded] ).

iOS 8 parece obligar a una vista a distribuir todas sus subvenciones, y luego configura restricciones en ella. iOS 7 no lo hará, y necesita que explícitamente le diga a las vistas que vuelvan a dibujar sus subvistas cuando cambie si está utilizando la reproducción automática.

En mi caso, UITextField y agregué una label al lado. Configuré el marco de la label agregando restricciones al UITextfield. Uno de los methods públicos que pude llamar en mi class fue

 - (void)setLabelText:(NSString *)newText{ self.sideLabel.text = newText; } 

Esto provocó que mi aplicación fallara cuando apareció un controller de vista que contenía mi campo de text subclasificado. Al agregar layoutIfNeeded todo funciona bien en iOS7 e iOS8.

 - (void)setLabelText:(NSString *)newText{ self.sideLabel.text = newText; [self layoutIfNeeded]; } 

Esto debe llamarse cada vez que cambie una parte de la vista en su subclass. Esto incluye la configuration cuando agrega subvenciones, cuando cambia las properties de visualización, cualquier cosa realmente. Antes de que la function que está cambiando su vista regrese, llame a layoutIfNeeded en su vista. Esto parece aplicarse a unos pocos controles de interfaz de usuario estándar, incluidos UITextfield, UITableView y UICollectionView, aunque estoy seguro de que hay otros. Espero que esto sea lo suficientemente claro y ayude a resolver su problema.

El error que obtienes no es muy útil, ni siquiera se aplicó en mi caso. Aunque estaba recibiendo exactamente el mismo error, ninguna de mis vistas implementaba layoutSubviews , y así todos estaban usando el método [super layoutSubviews] .

Este problema aparece en iOS <8

Al crear la subclass UIView y agregar vistas, podemos instruir al control para que construya y realice la reproducción automática primero de las subvistas. Use esta statement cuando la interfaz de usuario necesite ser actualizada:

[self layoutIfNeeded];

iOS 8+ está manejando el problema completamente allí internamente.

Tuve el mismo problema. Esto podría ser causado por restricciones incorrectas, tal vez por algunos establecidos en Storyboard. Intenta eliminar algunos de ellos y ver si funciona para averiguar qué está mal