viewDidLayoutSubviews en Autolayout con rotation en UIPageViewController

Tengo un UIPageViewController cuyos controlleres de vista contienen un UIScrollView que contiene un UIImageView . En la vista del controller de vista viewWillAppear , los límites son incorrectos si la vista gira. Aquí es donde estaba tratando de posicionar la vista de la image dinámicamente en function del tamaño de la image de acuerdo con esto . Traté de usar (void)viewDidLayoutSubviews pero necesito llamar a [self.view layoutSubviews] o me sale un error de aserción. Cuando agregué eso, ya no puedo ampliar la vista de la image. Puedes ver que intenta hacer zoom, pero vuelve a cambiar el tamaño al zoom mínimo.

Soy completamente nuevo en el layout automático y estaba tratando de ver si me estaba faltando algo.

Mi corrección actual implica verificar los límites del marco para ver si la orientación coincide con los límites. Si es así, uso los límites tal como están. Si no, entonces cambio el alto y ancho en mis cálculos.

Me gustaría saber cómo usar correctamente viewDidLayoutSubviews sin que me quite mi capacidad de acercar la vista de la image.

A partir de dos de las respuestas, parece que viewDidLayoutSubviews quizás sea el lugar incorrecto para distribuir las vistas. Estoy tratando de encontrar dónde debería hacerse esto y hacer que la vista conozca sus límites y orientación, pero antes de que sean visibles en la pantalla. De mi lectura, pensé que era viewDidLayoutSubviews pero parece que el uso podría conducir a un bucle infinito.

A partir de dos de las respuestas, parece que viewDidLayoutSubviews quizás sea el lugar incorrecto para distribuir las vistas. Estoy tratando de encontrar dónde debería hacerse esto y hacer que la vista conozca sus límites y orientación, pero antes de que sean visibles en la pantalla.

Subclass UIScrollView y layoutSubviews allí las layoutSubviews , que el sistema te llamará solo cuando sea necesario y cuando todas las variables (orientación, tamaño, etc.) tengan los valores adecuados.

En primer lugar, no debe llamar -layoutSubviews usted mismo. De la documentation de UIView para ese método :

No debe llamar a este método directamente. Si desea forzar una actualización de layout, llame al método setNeedsLayout en lugar de hacerlo antes de la próxima actualización de dibujo. Si desea actualizar el layout de sus vistas de inmediato, llame al método layoutIfNeeded.

Incluso sin la advertencia, llamar a ese método desde -viewDidLayoutSubviews parece ser una receta para problemas: -viewDidLayoutSubviews se llama para notificar a su controller de vista que su vista solo presenta subidas, por lo que llamar a [self.view layoutSubviews] podría conducir fácilmente a un loop.

En la vista del controller de vista cargadoWillAppear, los límites son incorrectos si la vista gira.

Recuerde que cuando se llama -viewWillAppear , la vista aún no se ha agregado a una jerarquía de vistas . Dado eso, parece que su enfoque actual no es malo. La vista todavía no tiene sus límites establecidos (porque aún no se ha agregado), por lo que puede determinar cuáles serán los límites y usarlos para configurar su vista. Otro, probablemente mejor enfoque sería usar -viewDidAppear , ya que su vista se habrá agregado en ese punto y debería tener los límites correctos para entonces.

Cuando agregué eso, ya no puedo ampliar la vista de la image. Puedes ver que intenta hacer zoom, pero vuelve a cambiar el tamaño al zoom mínimo.

Parece que no tomas en count el estado de zoom cuando posicionas la vista de la image. Asegúrese de que su código en -viewDidLayoutSubviews no esté negando el trabajo que está haciendo la vista de desplazamiento.

No debería necesitar cambiar la position de la vista de image en absoluto; ese es exactamente el tipo de layout automático que es bueno. Advierto que el file ImageScrollViewController.m que está utilizando como ejemplo no cambia la location de la vista de la image.

No estoy totalmente seguro acerca de la jerarquía de su vista, pero esta respuesta explica cómo hacerlo si tiene un controller de vista cuya vista contiene un UIScrollView. (Dicho controller de vista se muestra más adelante en UIPageViewController pero eso es irrelevante aquí).

Anule el siguiente método en su controller de vista que controla la vista de desplazamiento:

 - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; CGRect bounds = self.view.bounds; self.scrollView.frame = bounds; // // Calculate a rect for your image view according to bounds // self.imageView.frame = calculatedFrame; } 

El problema es que su vista se distribuirá durante el desplazamiento / zoom, y si coloca la vista en viewDidLayoutSubviews de un controller de vista que controla un scrollView, lo posicionará cada vez que el usuario desplace o amplíe.

Sospecho que su controller de vista podría estar controlando un UIScrollView directamente, (en lugar de controlar una vista que tiene una subvista UIScrollView), y en ese caso, simplemente quite la fila self.scrollView.frame = self.bounds .

Nunca debe llamar a [view.view.outlook]. ViewDidLayoutSubviews. De hecho, nunca deberías llamar a esa function en absoluto. Si necesita actualizar su layout, llame a [self.view setNeedsLayout]. Pero cuando su vista ha realizado su layoutSubviews, viewDidLayoutSubviews se llama automáticamente. Eso significa que si llamas a esa function desde allí, obtendrás un bucle infinito.