autolayout ios8 cgaffinetransform

autolayout - UIView no cambia de tamaño cuando se rota con CGAffineTransform en iOS8



(3)

Tengo un UIViewController que solo rota algunas de las subvistas cuando se gira el dispositivo. Esto funciona bien bajo iOS7 pero se rompe bajo iOS8. Parece que los límites de UIView se ajustan mediante la transformación bajo iOS8. Esto fue inesperado.

Aquí hay un código:

@interface VVViewController () @property (weak, nonatomic) IBOutlet UIView *pinnedControls; @property (nonatomic, strong) NSMutableArray *pinnedViews; @end @implementation VVViewController - (void)viewDidLoad { [super viewDidLoad]; self.pinnedViews = [NSMutableArray array]; [self.pinnedViews addObject:self.pinnedControls]; } -(void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; [UIViewController rotatePinnedViews:self.pinnedViews forOrientation:self.interfaceOrientation]; } - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation) && UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { [UIViewController rotatePinnedViews:self.pinnedViews forOrientation:toInterfaceOrientation]; } } @end

Hemos creado una categoría en UIViewController para manejar este comportamiento. Aquí está el código pertinente:

@implementation UIViewController (VVSupport) + (void)rotatePinnedViews:(NSArray *)views forOrientation:(UIInterfaceOrientation)orientation { const CGAffineTransform t1 = [UIViewController pinnedViewTansformForOrientation:orientation counter:YES]; const CGAffineTransform t2 = [UIViewController pinnedViewTansformForOrientation:orientation counter:NO]; [views enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) { // Rotate the view controller view.transform = t1; [view.subviews enumerateObjectsUsingBlock:^(UIView *counterView, NSUInteger idx, BOOL *stop) { // Counter-rotate the controlsUIin the view controller counterView.transform = t2; }]; }]; } + (CGAffineTransform)pinnedViewTansformForOrientation:(UIInterfaceOrientation)orientation counter:(BOOL)counter { CGAffineTransform t; switch ( orientation ) { case UIInterfaceOrientationPortrait: case UIInterfaceOrientationPortraitUpsideDown: t = CGAffineTransformIdentity; break; case UIInterfaceOrientationLandscapeLeft: t = CGAffineTransformMakeRotation(counter ? M_PI_2 : -M_PI_2); break; case UIInterfaceOrientationLandscapeRight: t = CGAffineTransformMakeRotation(counter ? -M_PI_2 : M_PI_2); break; } return t; } @end

Así es como se ve el plumín:

La UIView nombrada en la punta es la IBOutlet de pinnedControls:

Cuando ejecuto esto en modo retrato bajo iOS7 o iOS8 obtengo esto:

Y veo el resultado deseado en iOS7 en modo horizontal:

Pero en iOS8 (GM) no entiendo este comportamiento. Esto es lo que veo en su lugar:

Observe que el centro de UILabel con el texto "Etiqueta fija" mantiene su distancia desde la parte inferior de la UIView fija, que no ha cambiado de tamaño para acomodar la rotación. Esa UIView tiene todos sus bordes fijados en los lados superior, izquierdo, inferior y derecho de la supervista.

Me parece que la propiedad de transformación interactúa con Diseño automático de forma diferente en iOS8. Estoy un poco desconcertado aquí. Sé que no puedo confiar en el marco. Puede que simplemente empiece a establecer límites manualmente, pero eso parece ser lo que no debe hacer, esencialmente hacer una corrida final en Auto Layout.


Esto es más un trabajo que una solución, por lo que puede no ayudar a todos en situaciones similares. Mi problema era que la vista externa "fijada" se redimensionaba nuevamente después de aplicar la transformación.

Mi solución fue cambiar las restricciones en la vista anclada para centrar verticalmente, centrar horizontalmente y ancho y altura igual a una constante.

Luego, en viewDidLoad, configuro la altura y el ancho del marco de la vista fija para que sea el alto de la pantalla principal. Esto hace que la vista sea cuadrada, por lo que no me importa si se gira un poco más.


Esto me estaba volviendo loco durante los últimos días y pude solucionarlo cambiando el tiempo de la llamada setTransform en mi bloque de animaciones.

Cuando vaya al paisaje, estoy configurando la transformación DESPUÉS de configurar el nuevo marco. Cuando voy a retratos, estoy configurando la transformación ANTES de configurar el nuevo fotograma. Todo esto iba dentro del bloque de animaciones en el método "animateWithDuration ..."

No estoy seguro si te ayudará directamente con tu código, pero podría inspirar algo para resolverlo, ya que definitivamente tenemos un problema similar


en ios8, los controladores uiview deben redimensionarse con colecciones de colores dependiendo de la orientación del dispositivo. De lo contrario, obtienes una visualización en modo vertical, mientras que el teléfono está orientado en horizontal, cuando tratas de rotarlo. Entonces, los pasos correctos son rotar Y anular uitraitcollections

EDIT: anulo mi colección de uitrait con el siguiente código UITraitCollection *horTrait = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact]; UITraitCollection *verTrait = [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact]; UITraitCollection *finalTrait = [UITraitCollection traitCollectionWithTraitsFromCollections:@[horTrait,verTrait]]; [self.parentViewController setOverrideTraitCollection:finalTrait forChildViewController:self]; UITraitCollection *horTrait = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact]; UITraitCollection *verTrait = [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact]; UITraitCollection *finalTrait = [UITraitCollection traitCollectionWithTraitsFromCollections:@[horTrait,verTrait]]; [self.parentViewController setOverrideTraitCollection:finalTrait forChildViewController:self];

desafortunadamente, no funciona si el uiviewcontroller im tratando de modificar NO tiene un parentviewcontroller: ''(