vistas una tecnico secundarias proyeccion ortogonales ortogonal necesarias isometricas introduccion hacer dibujo como auxiliares angulos ios objective-c animation transitions uicontainerview

ios - una - vistas necesarias dibujo tecnico



Intercambio de vistas secundarias en una vista de contenedor (3)

Cuando tiene vistas secundarias que tienen sus propios controladores de vista, debe seguir el patrón de controlador de contenedor personalizado. Consulte Creación de controladores de vista de contenedor personalizados para obtener más información.

Suponiendo que haya seguido el patrón de contenedor personalizado, cuando desee cambiar el controlador de vista secundaria (y su vista asociada) para la "vista de contenido", lo haría mediante programación con algo como:

UIViewController *newController = ... // instantiate new controller however you want UIViewController *oldController = ... // grab the existing controller for the current "content view"; perhaps you maintain this in your own ivar; perhaps you just look this up in self.childViewControllers newController.view.frame = oldController.view.frame; [oldController willMoveToParentViewController:nil]; [self addChildViewController:newController]; // incidentally, this does the `willMoveToParentViewController` for the new controller for you [self transitionFromViewController:oldController toViewController:newController duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ // no further animations required } completion:^(BOOL finished) { [oldController removeFromParentViewController]; // incidentally, this does the `didMoveToParentViewController` for the old controller for you [newController didMoveToParentViewController:self]; }];

Cuando lo hace de esta manera, no hay necesidad de ninguna interfaz de protocolo de delegado con el controlador de la vista de contenido (que no sea lo que iOS ya proporciona con los Controladores de vista secundarios en un método de Contenedor personalizado ).

Por cierto, esto supone que el controlador secundario inicial asociado con esa vista de contenido se agregó así:

UIViewController *childController = ... // instantiate the content view''s controller any way you want [self addChildViewController:childController]; childController.view.frame = ... // set the frame any way you want [self.view addSubview:childController.view]; [childController didMoveToParentViewController:self];

Si desea que un controlador secundario le diga al padre que cambie el controlador asociado con la vista de contenido, usted:

  1. Definir un protocolo para esto:

    @protocol ContainerParent <NSObject> - (void)changeContentTo:(UIViewController *)controller; @end

  2. Defina el controlador principal para cumplir con este protocolo, por ejemplo:

    #import <UIKit/UIKit.h> #import "ContainerParent.h" @interface ViewController : UIViewController <ContainerParent> @end

  3. Implemente el método changeContentTo en el controlador principal (como se describe anteriormente):

    - (void)changeContentTo:(UIViewController *)controller { UIViewController *newController = controller; UIViewController *oldController = ... // grab reference of current child from `self.childViewControllers or from some property where you stored it newController.view.frame = oldController.view.frame; [oldController willMoveToParentViewController:nil]; [self addChildViewController:newController]; [self transitionFromViewController:oldController toViewController:newController duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ // no further animations required } completion:^(BOOL finished) { [oldController removeFromParentViewController]; [newController didMoveToParentViewController:self]; }]; }

  4. Y los controladores secundarios ahora pueden usar este protocolo en referencia a la propiedad self.parentViewController que iOS proporciona para usted:

    - (IBAction)didTouchUpInsideButton:(id)sender { id <ContainerParent> parentViewController = (id)self.parentViewController; NSAssert([parentViewController respondsToSelector:@selector(changeContentTo:)], @"Parent must conform to ContainerParent protocol"); UIViewController *newChild = ... // instantiate the new child controller any way you want [parentViewController changeContentTo:newChild]; }

Deje que ContainerView sea ​​la vista principal del contenedor con dos vistas de contenido secundario: NavigationView y ContentView .

Me gustaría poder cambiar el controlador de ContentView con otra vista. Por ejemplo, intercambiando un controlador de página de inicio con un controlador de página de noticias. Actualmente, la única forma en que puedo pensar para hacer esto es usar un delegado para decirle a ContainerView que quiero cambiar de vista. Esto parece una manera descuidada de hacer esto porque ContainerViewController terminaría teniendo un grupo de delegados especiales para todas las subvistas.

Esto también necesita comunicarse con NavigationView que tiene información sobre qué vista se encuentra actualmente en ContentView . Por ejemplo: si el usuario está en la página de noticias, la barra de navegación dentro de la vista de navegación mostrará que el botón de noticias está actualmente seleccionado.

Pregunta A: ¿Hay alguna forma de cambiar el controlador en ContentView sin un método de delegado llamando al propio ContainerView ? Me gustaría hacer esto programáticamente (sin guiones gráficos).

Pregunta B: ¿Cómo puedo cambiar los controladores en ContentView desde NavigationView sin una llamada de delegado? Me gustaría hacer esto programáticamente (sin guiones gráficos).


Para ese tipo de transición también puede usar UIView.animateWith... animations.

Por ejemplo, supongamos que rootContainerView es contenedor y contentViewController controlador activo actualmente en contenedor, luego

func setContentViewController(contentViewController:UIViewController, animated:Bool = true) { if animated == true { addChildViewController(contentViewController) contentViewController.view.alpha = 0 contentViewController.view.frame = rootContainerView.bounds rootContainerView.addSubview(contentViewController.view) self.contentViewController?.willMoveToParentViewController(nil) UIView.animateWithDuration(0.3, animations: { contentViewController.view.alpha = 1 }, completion: { (_) in contentViewController.didMoveToParentViewController(self) self.contentViewController?.view.removeFromSuperview() self.contentViewController?.didMoveToParentViewController(nil) self.contentViewController?.removeFromParentViewController() self.contentViewController = contentViewController }) } else { cleanUpChildControllerIfPossible() contentViewController.view.frame = rootContainerView.bounds addChildViewController(contentViewController) rootContainerView.addSubview(contentViewController.view) contentViewController.didMoveToParentViewController(self) self.contentViewController = contentViewController } } // MARK: - Private private func cleanUpChildControllerIfPossible() { if let childController = contentViewController { childController.willMoveToParentViewController(nil) childController.view.removeFromSuperview() childController.removeFromParentViewController() } }

esto le proporcionará animaciones de fade simples, también puede probar cualquier UIViewAnimationOptions , transiciones, etc.


Parece que te estás confundiendo. Un contentView (suponiendo que UIView ) no ''contiene'' un controlador que cambiaría. Un UIViewController maneja su UIView. Me parece que necesita una configuración de controlador de vista padre-hijo.

Un controlador de vista padre único, que manejaría los controles de vista secundarios, cada uno de los cuales puede manejar cuando se muestra cada uno en la pantalla y ajustar su UIViews y el contenido en consecuencia. Por favor, consulte la documentación de Apple a continuación.

Programación de Contenedores - Documentación de Apple