cocoa-touch uiview nslayoutconstraint

cocoa touch - Animate intrinsicContent Cambios de tamaño



cocoa-touch uiview (6)

Bueno, para Swift 4/3 esto funciona y creo que esta es la mejor práctica. Si tiene un UIView con un UILabel en él y el UIView adapta el marco del UILabel, use esto:

self.theUILabel.text = "text update" UIView.animate(withDuration: 5.0, animations: { self.theUIView.layoutIfNeeded() })

El self.view.layoutIfNeeded () normal también funcionará la mayor parte del tiempo.

Tengo una subclase UIView que dibuja un círculo cuyo radio cambia (con agradables animaciones hinchables). La vista es decidir el tamaño del círculo.

Quiero que esta subclase UIView cambie su tamaño de fotograma para que coincida con los cambios animados en el radio del círculo, y quiero que estos cambios modifiquen cualquier NSLayoutConstraints conectado a la vista (para que las vistas que están limitadas al borde del círculo se muevan como círculo cambia de tamaño).

Entiendo que implementar -(CGSize)intrinsicContentSize y llamar a invalidateIntrinsicContentSize cuando los cambios de radio indiquen las limitaciones para actualizar, pero no puedo imaginar cómo animar los cambios a intrinsicContentSize .

Llamar a invalidateIntrinsicContentSize desde dentro de un [UIView animateWith ... bloque simplemente actualiza instantáneamente el diseño.

¿Esto es posible, y hay un enfoque alternativo / mejor?


En el siguiente código, la clase intrínseca es la clase que acaba de cambiar su tamaño al cambiar una variable. Para animar la clase intrínseca, solo usa el siguiente código. Si afecta a otros objetos más arriba en la jerarquía de vista, entonces reemplace la clase self.intrinsic con la vista de nivel superior para setNeedsLayout y layout IfNeeded.

[UIView animateWithDuration:.2 animations:^{ self.intrinsicClass.numberOfWeeks=8; [self.intrinsicClass setNeedsLayout]; [self.intrinsicClass layoutIfNeeded]; }];


La restricción de ancho / altura no ayuda? Mantenga referencia de esta restricción y ...

[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:myViewInitialWidth];

... cuando quieras animar el tamaño de myView, haz esto ...

self.viewWidthConstraint.constant = 100; // new width [UIView animateWithDuration:0.3 animations:^{ [view layoutIfNeeded]; }];

... haz lo mismo para la altura.

Depende de tus otras limitaciones, tal vez te verás obligado a aumentar la prioridad de estas dos limitaciones.

O puede subclasificar UIView , agregar - (void)invalidateIntrinsicContentSize:(BOOL)animated y falsificarlo usted mismo. Obtenga un nuevo tamaño de - (CGSize)intrinsicContentSize y - (CGSize)intrinsicContentSize animando las restricciones de ancho / alto. O añada propiedad para habilitar / deshabilitar animaciones y anule invalidateIntrinsicContentSize y hágalo dentro de este método. Muchas maneras ...


Nada de esto me ha funcionado. Tengo un UILabel que configuro con un NSAttributedString. El texto es multilínea y se ajusta a los límites de las palabras. Por lo tanto, la altura es variable. He intentado esto:

[UIView animateWithDuration:1.0f animations:^{ self.label = newLabelText; [self.label invalidateIntrinsicContentSize]; [self.view setNeedsLayout]; [self.view layoutIfNeeded]; }];

Y una serie de variaciones. Ninguno funciona La etiqueta cambia inmediatamente su tamaño y luego se desliza a su nueva posición. Por lo tanto, la animación de la posición de las etiquetas en la pantalla está funcionando. Pero la animación del cambio de tamaño de la etiqueta no lo es.


invalidateIntrinsicContentSize funciona bien con animaciones y layoutIfNeeded . Lo único que debe tener en cuenta es que cambiar el tamaño del contenido intrínseco invalida el diseño de la supervista. Entonces esto debería funcionar:

[UIView animateWithDuration:0.2 animations:^{ [self invalidateIntrinsicContentSize]; [self.superview setNeedsLayout]; [self.superview layoutIfNeeded]; }];


Swift versión de la respuesta de @ stigi que funcionó para mí:

UIView.animate(withDuration: 0.2, animations: { self.invalidateIntrinsicContentSize() self.superview?.setNeedsLayout() self.superview?.layoutIfNeeded() })