ios - objective - Contenido empujado hacia abajo en un UIPageViewController con UINavigationController
uipageviewcontroller objective c (15)
ACTUALIZACIÓN 2
He estado ejecutando y probando mi aplicación en el simulador de iOS usando un dispositivo de 4 pulgadas. Si corro con un dispositivo de 3.5 pulgadas, la etiqueta no salta. En mi .xib, bajo Simulated Metrics, lo tengo configurado como Retina de 4 pulgadas de pantalla completa. ¿Alguna idea de por qué solo veo este problema en un dispositivo de 4 pulgadas?
ACTUALIZACIÓN 1
En IB, si elijo "Barra de navegación" en Metrología simulada, mi etiqueta sigue saltando. La única forma en que puedo hacer que mi etiqueta se visualice correctamente en la primera pantalla es no configurar un controlador de navegación como controlador de vista raíz de mi ventana.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
El control rootViewController de mi ventana se está configurando como UINavigationController, cuyo control raíz tiene un UIPageViewController incrustado.
Cuando se carga mi aplicación, la vista inicial se presenta con su contenido presionado un poco, más o menos del mismo tamaño que una barra de navegación. Cuando me desplazo por la página ViewController, el contenido salta hasta donde se colocó en el plumín, y todos los demás viewControllers cargados por el pageViewController están bien.
En mi appDelegate:
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[ContainerViewController new]];
En ContainerViewController:
- (void)viewDidLoad {
[super viewDidLoad];
self.pvc = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:nil];
self.pvc.dataSource = self;
self.pvc.delegate = self;
DetailViewController *detail = [DetailViewController new];
[self.pvc setViewControllers:@[detail]
direction:UIPageViewControllerNavigationDirectionForward
animated:false
completion:nil];
[self addChildViewController:self.pvc];
[self.view addSubview:self.pvc.view];
[self.pvc didMoveToParentViewController:self];
}
As @ djibouti33 ya publicado:
una página ViewController no pudo diseñar correctamente su controlador de vista secundaria inicialmente si contenía una vista de desplazamiento. en el momento en que estamos en layoutSubviews, pageViewController parece haber conseguido sus rodamientos y todo se presenta bien
Al esperar a que layoutSubViews se cargue antes de configurar ViewControllers al UIPageViewController fue lo único que funcionó para mí.
override func viewDidLoad() {
super.viewDidLoad()
self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "yourPageViewController") as? UIPageViewController
self.pageViewController?.dataSource = self
pageViewController?.automaticallyAdjustsScrollViewInsets = false
self.pageViewController?.view.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.height)
self.addChildViewController(self.pageViewController!)
self.view.addSubview((self.pageViewController?.view)!)
self.pageViewController?.didMove(toParentViewController: self)
}
override func viewDidLayoutSubviews() {
let startVC = self.viewControllerAtIndex(index: 0) as infoDataViewController
let viewControllers = NSArray(object: startVC)
self.pageViewController?.setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: true, completion: nil)
}
Así que estoy agregando otra respuesta después de un mayor desarrollo y finalmente creo que descubrí lo que está sucediendo. Parece que en iOS7, UIPageViewController tiene su propio UIScrollView. Debido a esto, debe establecer automaticallyAdjustsScrollViewInsets
AdjustsScrollViewInsets en falso. Aquí está mi viewDidLoad
ahora:
- (void)viewDidLoad
{
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = false;
DetailViewController *detail = [[DetailViewController alloc] init];
[self setViewControllers:@[detail]
direction:UIPageViewControllerNavigationDirectionForward
animated:false
completion:nil];
}
No es necesario poner nada a la viewWillLayoutSubviews
(como sugirió una de mis respuestas anteriores).
Esto definitivamente está causado por los automaticallyAdjustsScrollViewInsets
de automaticallyAdjustsScrollViewInsets
, como otros carteles (incluido @ djibouti33). Sin embargo, esta propiedad es extraña de dos maneras:
- Debe estar configurado en un
UINavigationController
. Si lo configura en un controlador secundario administrado por unUINavigationController
, no tendrá ningún efecto. 1 - Solo se aplica cuando una vista de desplazamiento está en el índice cero en las subvistas de un controlador. 2
Estas dos advertencias deberían explicar los problemas intermitentes experimentados por otros en el hilo.
TLDR: una solución con la que fui es agregar una vista ficticia al UIPageViewController
en el índice cero, para evitar la configuración que se aplica a scrollView dentro del controlador de página, como esta:
pageViewController.view.insertSubview(UIView(), atIndex: 0) // swift
[pageViewController.view insertSubview: [UIView new] atIndex: 0]; // obj-c
Mejor sería configurar el contentInset
en la vista de desplazamiento usted mismo, pero desafortunadamente el UIPageViewController
no expone la vista de desplazamiento.
Estoy viendo el mismo problema descrito por @Danny en iOS 9. Intenté actualizar todas mis restricciones para que no estén limitadas a los márgenes , pero no solucionó el problema. Terminé teniendo que adoptar un truco similar a este de la siguiente manera;
- Para cada página de contenido que se mostrará en UIPageViewController, encuentre la restricción más alta, la que se encuentra entre la parte superior de una vista y la parte inferior de la guía de diseño superior, y agréguele una salida al controlador de vista.
En cada controlador de vista con tal salida, agregue otra propiedad para la distancia superior preferida. Los dos puntos de venta se ven así (en Swift):
@IBOutlet weak var topGuideConstraint: NSLayoutConstraint! var topDistance: CGFloat!
En
viewDidLoad()
, establezcatopDistance
en el valor asignado a la restricción en el guión gráfico:override func viewDidLoad() { super.viewDidLoad() topDistance = topGuideConstraint.constant }
En
viewWillLayoutSubviews()
, asegúrese de que la restricción tenga el valor adecuado, ajustándose a la altura de la barra de estado cuandotopLayoutGuide.length
sea cero, lo que parece ser el caso durante la transición , pero no una vez que se complete:override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() topGuideConstraint.constant = topDistance + ( topLayoutGuide.length == 0 ? UIApplication.sharedApplication().statusBarFrame.size.height : 0 ) }
Repita para cada controlador de vista de contenido que se muestra en UIPageViewController. Ajuste la compensación según corresponda si también está mostrando una barra de navegación UIN.
Este es un truco desafortunado, y odio tener que hacerlo, pero después de muchas horas intentando cosas diferentes, al menos estoy feliz de tener algo que funcione para poder seguir adelante.
Inicialmente mi jerarquía de controlador de vista se veía así:
-- UINavigationController
-- MyContainerViewController
-- UIPageViewController
-- MyDetailViewController
Lo configuré de esta forma para que MyContainerViewController pudiera administrar una barra de herramientas. Reduje mi problema a MyContainerViewController, y luego se me ocurrió que ni siquiera lo necesito si hago una subclase de UIPageViewController. Ahora mi jerarquía se ve así:
-- UINavigationController
-- MyPageViewController
-- MyDetailViewController
MyPageViewController
administra su toolbar
de toolbar
, y todo funciona como se espera, tanto en un dispositivo de 4 pulgadas como de 3,5 pulgadas.
Intente seleccionar PageViewController en el guión gráfico y desmarque "Debajo de las barras inferiores" y "Debajo de las barras opacas" en Attributes Inspector.
La versión de Swift de la respuesta de djibouti33 (excluyendo la línea que no es parte de la resolución del problema)
Swift 3.0
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
}
Mi respuesta original resolvió el problema por el momento, pero después de un tiempo el mismo problema volvió para morderme.
Usando la siguiente jerarquía viewController:
-- UINavigationController
-- MyPageViewController
-- MyDetailViewController
Esto es lo que hice para resolverlo:
En MyPageViewController.m
@interface MyPageViewController () <delegates>
@property (strong) MyDetailViewController *initialViewController;
@end
- (void)viewDidLoad
{
...
// set this once, because we''re going to use it in viewWillLayoutSubviews,
// which gets called multiple times
self.initialViewController = [MyDetailViewController new];
}
// the problem seemed to stem from the fact that a pageViewController couldn''t
// properly lay out it''s child view controller initially if it contained a
// scroll view. by the time we''re in layoutSubviews, pageViewController seems to
// have gotten it''s bearings and everything is laid out just fine.
- (void)viewWillLayoutSubviews
{
[self setViewControllers:@[self.initialViewController]
direction:UIPageViewControllerNavigationDirectionForward
animated:false
completion:nil];
}
Ninguno de los anteriores funcionó para mí
Aquí encontré la solución
var pageMenu : CAPSPageMenu?
En lugar de agregar así
self.view.addSubview(pageMenu!.view)
Agregue su CAPSPageMenu como a continuación
addChildViewController(pageMenu!)
self.view.addSubview(pageMenu!.view)
pageMenu!.didMove(toParentViewController: self)
Referencia: iOS Swift: SlidingMenuView Posición incorrecta después de presentar imagePicker
Feliz Codificación!
Según lo indicado por "Bo:": Put self.edgesForExtendedLayout = UIRectEdgeNone; en el viewDidLoad de MyPageViewController resolvió el problema. - Bo
Tengo el mismo problema. Lo resuelvo poniendo setViewControllers para la primera página en viewDidLoad de UIPageViewController en lugar de configurarlo cuando hago una instancia de UIPageViewController. Además, necesito establecer automáticamente AdjustsScrollViewInsets en NO.
Tuve un problema similar, pero ninguna de las soluciones aquí funcionó. Mi problema era que cada vez que me desplazaba a la página siguiente, el contenido saltaba, terminando en la posición correcta, pero comenzando a 20 píxeles demasiado alto (algo que claramente tiene que ver con la barra de estado). Mi contenedor VC no era un VC de navegación. Después de sacarme el pelo por un tiempo, la solución que terminó trabajando para mí fue solo asegurarme de que ninguna de las restricciones en mi contenido VC estuviera conectada a la guía de diseño superior. Esto puede o no ser factible en su caso, pero en el mío sí lo fue, y fue lo único que resolvió el salto de contenido. También muy curiosamente, este problema solo se manifestó cuando el estilo de transición estaba configurado para desplazarse. El simple hecho de cambiarlo a la página curl hizo que el problema desapareciera. Pero necesitaba desplazamiento. Espero que esto ayude a alguien más.
esta es la primera vez que publico sobre desbordamiento de pila, pero he estado buscando una solución a este problema por más de una semana.
Aquí hay una solución que se me ocurrió, espero que esto funcione para cualquier otra persona con el mismo problema.
No estoy seguro de cómo está inicializando su marco para su controlador de vista detallada, pero supongo que podría usar: self.view.frame.size.height;
intente usar: self.view.frame.size.height - = self.navigationController.navigationBar.bounds.size.height;
Espero que esto ayude