¿Por qué no puedo colocar la vista maestra y de detalle una junto a la otra en UISplitViewController en la primera ejecución, pero al girar funciona?

Tengo un controller de vista dividida que tiene una list de elementos a la izquierda y una vista de detalles a la derecha. Código relevante en AppDelegate:

let splitViewController = mainView.instantiateViewControllerWithIdentifier("initial") as! UISplitViewController let rightNavController = splitViewController.viewControllers.last as! UINavigationController let detailViewController = rightNavController.topViewController as! DetailsIpad let leftNavController = splitViewController.viewControllers.first as! UINavigationController let masterViewController = leftNavController.topViewController as! MainViewController masterSplitViewController = masterViewController detailSplitViewController = detailViewController // Override point for customization after application launch. let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem() splitViewController.delegate = self self.window!.rootViewController = splitViewController 

Cuando presento la aplicación por primera vez, veo que la parte derecha de la pantalla dividida ocupa toda la pantalla:

introduzca la descripción de la imagen aquí

Si giro la pantalla, se establece correctamente (probablemente porque ambas vistas están presentes en la pantalla):

introduzca la descripción de la imagen aquí

Cuando establezco puntos de interrupción en todas partes, veo que la vista de detalle de la derecha se carga antes de la vista maestra de la izquierda (list de elementos), a pesar de que no se llama directamente. No puedo cambiar el order en que se llaman las vistas de la pantalla dividida. ¿Cómo puedo arreglar esto?

ACTUALIZAR:

Puedo configurar esto antes de mostrar el controller de vista dividida:

 splitViewController.prefernetworkingDisplayMode = UISplitViewControllerDisplayMode.AllVisible 

Y en ViewDidLoad del controller dividido cuando lo imprimo:

 print(self.prefernetworkingDisplayMode.rawValue) 

Obtengo: 2, que es AllVisible. Pero aún el resultado es el mismo.

Es el comportamiento pnetworkingeterminado de UISplitViewController . Mira de cerca lo siguiente:

 // An animatable property that controls how the primary view controller is hidden and displayed. A value of `UISplitViewControllerDisplayModeAutomatic` specifies the default behavior split view controller, which on an iPad, corresponds to an overlay mode in portrait and a side-by-side mode in landscape. @property (nonatomic) UISplitViewControllerDisplayMode prefernetworkingDisplayMode NS_AVAILABLE_IOS(8_0); 

Aquí está la parte key de la misma definición:

en un iPad, corresponde a un modo de superposition en retrato y un modo de lado a lado en el paisaje.

Además, si desea consultar el estado actual (modo de visualización) de un UISplitViewController , debe usar esta propiedad-

 // The actual current displayMode of the split view controller. This will never return `UISplitViewControllerDisplayModeAutomatic`. @property (nonatomic, readonly) UISplitViewControllerDisplayMode displayMode NS_AVAILABLE_IOS(8_0); 

Y recuerde, no puede comparar esto con UISplitViewControllerDisplayModeAutomatic :

Esto nunca devolverá UISplitViewControllerDisplayModeAutomatic .

Mi sugerencia sería configurar prefernetworkingDisplayMode en el valor que desea. En su caso, parece que necesita que el principal (maestro) esté siempre visible. Entonces esta es la solución propuesta:

 mySplitVC.prefernetworkingDisplayMode = UISplitViewControllerDisplayModeAllVisible 

¿Por qué carga primero el controller secundario (detalle)?

Como puede ver, una instancia de UISplitViewController siempre necesita una vista de detalle sin importar en qué displayMode se encuentre actualmente. Entonces es una buena llamada para

  • Primero cargue la vista de detalle.
  • Cargue la vista primaria después (con base condicional en displayMode).

Espero que esto ayude.

Gracias @Tarun Tyagi por la explicación, pero en mi caso las acciones sugeridas no funcionaron. Sin embargo, esto funcionó para mí: en el SplitViewController agregué una llamada para setNeedsLayout ():

 override func viewDidAppear(animated: Bool) { self.view.setNeedsLayout() } 

Eso hará que la vista se actualice cuando la vista ya esté en la pantalla.