How to dismiss own view controller and present another view controller in a button tap?
Solution 1
you can do using protocol let say for example as bellow:-
In to your B viewController setting 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
in .m class
- (IBAction)ButtonTap:(id)sender
{
[self.delegate BviewcontrollerDidTapButton:self];
}
Now in to you A_viewController .h class:
#import "Bviewcontroller.h"
@interface A_viewController : UIViewcontroller<BviewControllerDelegate>
.m class
- (void)BviewcontrollerDidTapButton:
(Bviewcontroller *)controller
{
[self dismissViewControllerAnimated:YES completion:^{
// here you can create a code for presetn C viewcontroller
}];
}
IMPORTANT when you preseting Bviewcontroller from A_viewController do not set delegate with object like
-(void)presentNextViewCon
{
bViewcontroller *gestureViewCon = [[bViewcontroller alloc]init];
gestureViewCon.delegate = self;
[self presentViewController:gestureViewCon animated:YES completion:nil];
}
UPDATE
Here it is i create a demo that working like:
SAMPLE CODE LINK http://speedy.sh/2acSC/modelDemo.zip
Solution 2
You are taking about a Button lets name it controlButton. Pass that button with B and C with custom init method. That means your UIViewController A is having controllButton reference. Using the method
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
set the trigger block in A and like this
[_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];
}];
}
But the best option is to go with “Mediator Design pattern” where a coordinator is coordinating your present and dismiss actions.
Solution 3
It seems that it is not possible to go from B to C without showing A briefly, which looks unprofessional. However, you can put a black subview over top of A until you've animated to C.
In 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
{
...
}
Solution 4
You can not dismiss B and present C simultaneously.
To perform this task you should follow some tasks.
- On pressing button on 'B' , Dissmiss 'B' without animation and set an global BOOL variable to notify that you want to present 'C'.
On -(void)viewDidAppear:(BOOL)animated of 'A'
if (bool){ [self presentViewController:c animated:YES completion:nil]; }
user3526002
Updated on September 04, 2020Comments
-
user3526002 over 3 years
Let's say I have 3 view controller labeled "A","B" and "C". Right now, "A" is the rootViewController of the window and it presents "B" modally when a button is tapped. In "B", when a button is tapped it is supposed to be dismissed by "A" and then "A" will present C modally immediately.How can one do that? Here's my code in hope of achieving this goal but I was unsuccessful in doing so.
At "A" viewController, I declared a property to hold a block at the header file to be called when "B" viewController is dismissed by "A".
@property (nonatomic, copy) void (^presentZapLaunch)(void);
This is "A" viewController present method to present "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]; }
This is "B" dismiss method to dismissed by "A" and "A" should present "C" immediately
-(void)presentNextViewCon { NSLog(@"Hello"); [self.presentingViewController dismissViewControllerAnimated:self completion:^{[(CYCZapZapViewController *)self.presentingViewController presentZapLaunch];}]; }
*Note that I'm using "A" view controller as the rootViewController of window, and "A" presents "B" view controller modally. All "A","B" and "C" are view controllers.