Oh hombre, esto me estaba causando dolor de cabeza durante unos días y no podía encontrar la manera de hacerlo. La peor parte fue que crear un nuevo proyecto Xcode iOS con la plantilla master-detail funcionó bien. Afortunadamente, al final, ese pequeño hecho fue cómo encontré la solución.
Hay algunas publicaciones que he encontrado que sugieren que la solución es implementar el nuevo primaryViewControllerForCollapsingSplitViewController:
método UISplitViewControllerDelegate
. Lo intenté en vano. Lo que Apple hace en la plantilla de detalles maestros que parece funcionar es implementar el nuevo splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
método delegado ( respire profundamente para decir todo esto) (nuevamente encendido UISplitViewControllerDelegate
). Según los documentos , este método:
Pide al delegado que ajuste el controlador de vista primario e incorpore el controlador de vista secundario en la interfaz contraída.
Asegúrese de leer la parte de discusión de ese método para obtener detalles más específicos.
La forma en que Apple maneja esto es:
- (BOOL)splitViewController:(UISplitViewController *)splitViewController
collapseSecondaryViewController:(UIViewController *)secondaryViewController
ontoPrimaryViewController:(UIViewController *)primaryViewController {
if ([secondaryViewController isKindOfClass:[UINavigationController class]]
&& [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[DetailViewController class]]
&& ([(DetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil)) {
// Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
return YES;
} else {
return NO;
}
}
Esta implementación básicamente hace lo siguiente:
- Si
secondaryViewController
es lo que esperamos (a UINavigationController
), y muestra lo que esperamos (a DetailViewController
- su controlador de vista), pero no tiene modelo ( detailItem
), entonces " Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
"
- De lo contrario, regrese "
NO
para permitir que el controlador de vista dividida intente incorporar el contenido del controlador de vista secundario en la interfaz contraída"
Los resultados son los siguientes para el iPhone en vertical (ya sea comenzando en vertical o girando a vertical, o una clase de tamaño compacto más precisa):
- Si tu opinión es correcta
- y tiene un modelo, muestra el controlador de vista detallada
- pero no tiene modelo, muestra el controlador de vista maestro
- Si su punto de vista no es correcto
- mostrar el controlador de vista maestro
Claro como el barro.
UISplitViewController
y siempre regresoYES
de ese método, luego solo cambié la clase de vista dividida en Storyboard, ya que siempre quiero mostrar el maestro en iPhone en vertical. :)UISplitViewController
pero descubrí que eso no funcionaba:splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
nunca se llamaba. En cambio, copié la plantilla de Apple y la puse en AppDelagate. Esto también requirió algunos cambios para crear el UISplitViewControllerapplication didFinishLaunchingWithOptions:
(donde también copié la plantilla de Apple).splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
nunca me llaman. Parece que el delegado está configurando correctamente elapplicationDidFinishLaunchingWithOptions:
método de delegado de mi aplicación . ¿Alguien más ha visto este problema y NO ha funcionado esta solución?Aquí está la respuesta aceptada en Swift. Simplemente cree esta subclase y asígnela a su splitViewController en su guión gráfico.
fuente
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
Versión rápida de la respuesta correcta de Mark S
Según lo provisto por la plantilla Master-Detail de Apple.
Aclaración
(Lo que dijo Mark S fue un poco confuso)
Este método de delegado se llama
splitViewController: collapseSecondaryViewController: ontoPrimaryViewController:
, porque eso es lo que hace. Al cambiar a un tamaño de ancho más compacto (por ejemplo, al girar el teléfono de horizontal a vertical), debe contraer el controlador de vista dividida en solo uno de ellos.Esta función devuelve un valor booleano para decidir si debe contraer el detalle y mostrar el maestro o no.
Entonces, en nuestro caso, decidiremos en función de si se seleccionó un detalle o no. ¿Cómo sabemos si se seleccionan nuestros detalles? Si seguimos la plantilla Master-Detail de Apple, el controlador de vista detallada debería tener una variable opcional que tenga la información detallada, por lo que si es nula (.Ninguna), todavía no hay nada seleccionado y deberíamos mostrar el Master para que el usuario pueda seleccionar algo.
Eso es.
fuente
Apple's Master-Detail template
, no pretende ser grandioso o conciso, solo fáctico. :)De la documentación , debe usar un delegado para decirle al
UISplitViewController
no incorpore la vista detallada en la "interfaz contraída" (es decir, el "modo vertical" en su caso). En Swift 4, se ha cambiado el nombre del método delegado para implementar:fuente
.metro:
fuente
Mi aplicación fue escrita en Swift 2.xy podría funcionar bien. Después de convertirlo a Swift 3.0 (usando el convertidor XCode), comienza a mostrar detalles primero en lugar de master en modo vertical. El problema es que el nombre de la función splitViewController no se cambia para que coincida con la nueva de UISplitViewControllerDelegate.
Después de cambiar el nombre de esa función manualmente, mi aplicación ahora puede funcionar correctamente:
fuente
self.delegate = self
elviewDidLoad
método.Si no tiene valores predeterminados para mostrar en el controlador de vista detallada, simplemente puede eliminar el segue predeterminado entre el SplitViewController y su UIViewController detallado en el guión gráfico. Esto hará que siempre entre primero en Master View Controller.
El efecto secundario de esto es que, en lugar de ver dos vistas en horizontal, verá una vista en tamaño completo en SplitViewController hasta que se active Mostrar detalle Segue en el controlador de vista maestro.
fuente
Para todas las personas que no pudieron encontrar la sección del viernes de cs193p:
En Swift 3.1.1, crear una subclase de UISplitViewController e implementar uno de sus métodos delegados me funcionó de maravilla:
Mi storyboard
fuente
public func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool
En mi opinión, deberías resolver este problema más genérico. Puede subclasificar el UISplitViewController e implementar un protocolo en los controladores de vista integrados.
Implementación de ejemplo en UITableViewController:
Espero eso ayude. Entonces puede reutilizar esta clase y solo necesita implementar un protocolo.
fuente
Simplemente quite DetailViewController de los controladores SplitView cuando lo necesite para comenzar desde Master.
fuente
Esto funcionó para mí en iOS-11 y Swift 4:
fuente
La función cambia de nombre en las nuevas versiones de Swift, por lo que este código funciona en Swift 4:
fuente
Solución Xamarin / C #
fuente
Simplemente establezca la
preferredDisplayMode
propiedad deUISplitViewController
a.allVisible
fuente