ios 如何关闭自己的视图控制器并在按钮点击中显示另一个视图控制器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23930474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to dismiss own view controller and present another view controller in a button tap?
提问by user3526002
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.
假设我有 3 个标记为“A”、“B”和“C”的视图控制器。现在,“A”是窗口的 rootViewController,当点击按钮时它以模态呈现“B”。在“B”中,当一个按钮被点击时,它应该被“A”解除,然后“A”将立即以模态方式呈现 C。如何做到这一点?这是我希望实现这一目标的代码,但我没有成功。
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".
在“A”viewController 中,我声明了一个属性来在头文件中保存一个块,当“B”viewController 被“A”解除时将被调用。
@property (nonatomic, copy) void (^presentZapLaunch)(void);
This is "A" viewController present method to present "B"
这是呈现“B”的“A”viewController呈现方法
-(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
这是被“A”解雇的“B”解雇方法,“A”应立即呈现“C”
-(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.
*请注意,我使用“A”视图控制器作为窗口的rootViewController,“A”以模态方式呈现“B”视图控制器。所有“A”、“B”和“C”都是视图控制器。
回答by Nitin Gohel
you can do using protocol let say for example as bellow:-
您可以使用协议来做,例如如下:-
In to your B viewController setting Protocol :
在您的 B viewController 设置协议中:
@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
在 .m 班
- (IBAction)ButtonTap:(id)sender
{
[self.delegate BviewcontrollerDidTapButton:self];
}
Now in to you A_viewController .h class:
现在进入 A_viewController .h 类:
#import "Bviewcontroller.h"
@interface A_viewController : UIViewcontroller<BviewControllerDelegate>
.m class
.m 类
- (void)BviewcontrollerDidTapButton:
(Bviewcontroller *)controller
{
[self dismissViewControllerAnimated:YES completion:^{
// here you can create a code for presetn C viewcontroller
}];
}
IMPORTANTwhen you preseting Bviewcontroller from A_viewController do not set delegate with object like
重要的是,当您从 A_viewController 预设 Bviewcontroller 时,请勿使用对象设置委托,例如
-(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 LINKhttp://speedy.sh/2acSC/modelDemo.zip
回答by Goppinath
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
您正在考虑一个 Button,让它命名为 controlButton。使用自定义 init 方法通过 B 和 C 传递该按钮。这意味着你的 UIViewController A 有 controlButton 引用。使用方法
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
set the trigger block in A and like this
在 A 中设置触发块,然后像这样
[_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.
但最好的选择是使用“中介者设计模式”,在这种模式下,协调者协调你的当前和解除行动。
回答by Sandeep Singh
You can not dismiss B and present C simultaneously.
你不能同时解散 B 和呈现 C。
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]; }
- 在按下 'B' 上的按钮时,关闭没有动画的 'B' 并设置一个全局 BOOL 变量以通知您想要呈现 'C'。
在 -(void)viewDidAppear:(BOOL) 动画的“A”
if (bool){ [self presentViewController:c 动画:YES 完成:nil]; }
回答by prewett
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.
从B到C,不简单地展示A似乎是不可能的,这看起来很不专业。但是,您可以在 A 的顶部放置一个黑色子视图,直到您将动画设置为 C。
In Swift 3:
在 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
{
...
}