¿Cómo descartar el controller de vista propia y presentar otro controller de vista con un toque de button?

Digamos que tengo el controller de 3 vistas labeldo como "A", "B" y "C". En este momento, "A" es el rootViewController de la window y presenta "B" de manera modal cuando se toca un button. En "B", cuando se toca un button, se supone que debe ser descartado por "A" y luego "A" presentará C modalmente inmediatamente. ¿Cómo se puede hacer eso? Aquí está mi código con la esperanza de lograr este objective, pero no tuve éxito al hacerlo.

En "A" viewController, declaré una propiedad para contener un bloque en el file de encabezado que se llamará cuando "B" viewController sea descartado por "A".

@property (nonatomic, copy) void (^presentZapLaunch)(void); 

Este es el método presente "A" viewController para presentar "B"

 -(void)presentNextViewCon { CYCGestureZapZapViewController *gestureViewCon = [[CYCGestureZapZapViewController alloc]init]; if (!self.presentZapLaunch) { __weak CYCZapZapViewController *weakRefCon = self; self.presentZapLaunch = ^{ CYCZapZapViewController *preventWeakRefCon = weakRefCon; CYCZapZapLaunchViewController *zapLaunch = [[CYCZapZapLaunchViewController alloc]init]; NSLog(@"Called"); [preventWeakRefCon presentViewController:zapLaunch animated:YES completion:nil]; }; } [self presentViewController:gestureViewCon animated:YES completion:nil]; } 

Este es el método de rechazo "B" para ser descartado por "A" y "A" debe presentar "C" inmediatamente

 -(void)presentNextViewCon { NSLog(@"Hello"); [self.presentingViewController dismissViewControllerAnimated:self completion:^{[(CYCZapZapViewController *)self.presentingViewController presentZapLaunch];}]; } 

* Tenga en count que estoy usando el controller de vista "A" como la window rootViewController y "A" presenta el controller de vista "B" de manera modal. Todos "A", "B" y "C" son controlleres de vista.

puede hacer uso de protocolo, digamos, por ejemplo, como a continuación:

En su configuration B viewController Protocol:

 @class Bviewcontroller; @protocol BviewControllerDelegate <NSObject> - (void)BviewcontrollerDidTapButton: (Bviewcontroller *)controller; @end @interface Bviewcontroller : UIViewcontroller @property (nonatomic, weak) id <BviewControllerDelegate> delegate; - (IBAction)ButtonTap:(id)sender; @end 

en la class .m

 - (IBAction)ButtonTap:(id)sender { [self.delegate BviewcontrollerDidTapButton:self]; } 

Ahora en usted A_viewController .h class:

 #import "Bviewcontroller.h" @interface A_viewController : UIViewcontroller<BviewControllerDelegate> 

class .m

 - (void)BviewcontrollerDidTapButton: (Bviewcontroller *)controller { [self dismissViewControllerAnimated:YES completion:^{ // here you can create a code for presetn C viewcontroller }]; } 

IMPORTANTE cuando presintoniza Bviewcontroller desde A_viewController no establece delegado con object como

 -(void)presentNextViewCon { bViewcontroller *gestureViewCon = [[bViewcontroller alloc]init]; gestureViewCon.delegate = self; [self presentViewController:gestureViewCon animated:YES completion:nil]; } 

ACTUALIZAR

Aquí es donde creo una demostración que funciona como:

introduzca la descripción de la imagen aquí

CÓDIGO DE EJEMPLO LINK http://speedy.sh/2acSC/modelDemo.zip

Está tomando un button que le permite nombrarlo controlButton. Pase ese button con B y C con el método init personalizado. Eso significa que su UIViewController A tiene reference de controllButton. Usando el método

 - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents 

establezca el bloque de disparo en A y así

 [_controllButton addTarget:self action:@selector(controllButtonTapped:)....]; - (void)controllButtonTapped:(id)sender { [self dismissViewControllerAnimated:YES completion:^{ // present you c here [self presentViewController:c animated:YES completion:NULL]; }]; } 

Pero la mejor opción es ir con "Patrón de layout de mediador" donde un coordinador coordina su presente y descarta acciones.

No puede descartar B y presentar C simultáneamente.

Para realizar esta tarea, debe seguir algunas tareas.

  • Al presionar el button en 'B', Dissmiss 'B' sin animation y establecer una variable BOOL global para notificar que desea presentar 'C'.
  • Activado – (vacío) viewDidAppear: (BOOL) animado de 'A'

    if (bool) {[self presentViewController: c animated: YES completion: nil]; }

Parece que no es posible pasar de B a C sin mostrar A brevemente, lo que parece poco profesional. Sin embargo, puede poner una subvista negra sobre la parte superior de A hasta que haya animado a C.

En Swift 3:

 class A : UIViewController { ... func showB() { // Adding the black view before dismissing B does not work; // the view is not displayed. let black = UIView() black.backgroundColor = UIColor.black black.frame = self.view.bounds // assumes A is not zoomed let b = B() self.present(b, animated:true, completion: { self.view.addSubview(black) }) // Note: self.present() will start the animation, // then b.imDone will be set. It is done here for // clarity of what happens next, as if it were all // one function. b.imDone = { b.dismiss(animated:false, completion: { self.present(C(), animated:true, completion: { black?.removeFromSuperview() }) }) } } } class B : UIViewController { var imDone : (() -> Void)? ... func f() { imDone?() } ... } class C : UIViewController { ... }