xcode 关闭当前视图控制器中的前一个模态视图控制器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25221606/
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
Dismiss previous modal view controller in current view controller
提问by tnylee
I currently have 3 ViewControllers: LoginViewController
, SignUpViewController
and MainViewController
.
我目前有 3 个 ViewControllers: LoginViewController
,SignUpViewController
和MainViewController
.
When the user opens the app, LoginViewController
will be presented. If its the user's first time using the app then they will have to sign up, the "Sign Up" button is in the LoginViewController
. The "Sign Up" button will bring up the SignUpViewController
.
当用户打开应用程序时,LoginViewController
将呈现。如果用户是第一次使用该应用程序,则他们必须注册,“注册”按钮位于LoginViewController
. “注册”按钮将显示SignUpViewController
.
Once the user finished signing up. The MainViewController
will be presented.
一旦用户完成注册。在MainViewController
将提交。
What I am trying to do is. In the MainViewController
there will be a "Log Out" button. When the user press it the MainViewController
should be dismissed and LoginViewController
should be there. The user should not see the SignUpViewController
for the second time.
我正在尝试做的是。在MainViewController
将有“注销”按钮。当用户按下它时,MainViewController
应该被解雇并且LoginViewController
应该在那里。用户不应SignUpViewController
第二次看到。
Here is what I have tried:
这是我尝试过的:
1) Dismiss SignUpViewController
and present MainViewController
in "sign up" button:
1) 关闭SignUpViewController
并出现MainViewController
在“注册”按钮中:
- (void) signUpClicked
{
MainViewController *mainViewController = [viewController.storyboard instantiateViewControllerWithIdentifier:@"MainViewController"];
[viewController presentViewController:mainViewController animated:YES completion:^{
[viewController dismissViewControllerAnimated:NO completion:^{
}];
}];
}
2) When MainViewController
loads, dismiss SignUpViewController
2)MainViewController
加载时,解除SignUpViewController
- (void)viewDidLoad
{
[super viewDidLoad];
SignUpViewController *signUpViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SignUpViewController"];
[signUpViewController dismissViewControllerAnimated:NO completion:^{
}];
}
回答by tnylee
Got it. I passed the SignUpViewController to the MainViewController and dismiss the SignUpViewController in the MainViewController.
知道了。我将 SignUpViewController 传递给 MainViewController 并关闭 MainViewController 中的 SignUpViewController。
For anyone else who had the same question as me.
对于和我有同样问题的其他人。
SignUpViewController.m
注册ViewController.m
- (void) signUpButtonClicked
{
MainViewController *mainViewController = [viewController.storyboard instantiateViewControllerWithIdentifier:@"MainViewController"];
mainViewController.signUpViewController = viewController;
[viewController presentViewController:mainViewController animated:YES completion:^{
}];
}
MainViewController.m
主视图控制器.m
- (IBAction)logoutClicked:(id)sender
{
[self dismissViewControllerAnimated:YES completion:^{
[self.signUpViewController dismissViewControllerAnimated:NO completion:^{
}];
}];
}
回答by Acey
presentViewController can get you a long ways, but maybe you should roll your own Container View Controller. They're pretty dang easy! The UIContainerViewControllerProtectedMethods category on UIViewController outlines what methods you can/should use.
presentViewController 可以让你走很长的路,但也许你应该推出自己的容器视图控制器。他们很容易!UIViewController 上的 UIContainerViewControllerProtectedMethods 类别概述了您可以/应该使用的方法。
The basic gist is you have a container View Controller that adds child View Controllers to itself and their views as subviews of its own view. The main method that does the heavy lifting is:
基本要点是您有一个容器视图控制器,它将子视图控制器添加到自身及其视图作为其自身视图的子视图。完成繁重工作的主要方法是:
... transitionFromViewController:(UIViewController *)fromViewController
toViewController:(UIViewController *)toViewController
duration:(NSTimeInterval)duration
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion
In the animations section, you can do whatever sort of movement you want. In your case, you would want to put the LoginViewController's view behind the MainViewController's view, and move the MainViewController's view offscreen. You get to supply your own animation options, so the appearance will move similarly to how dismissViewController looks now.
在动画部分,你可以做任何你想做的运动。在您的情况下,您可能希望将 LoginViewController 的视图放在 MainViewController 的视图后面,并将 MainViewController 的视图移出屏幕。您可以提供自己的动画选项,因此外观的移动方式将与现在的 dismissViewController 的外观类似。
It's a bit more overhead to get set up, but View Controller Containment gives you a lot of flexibility and power.
设置的开销有点大,但 View Controller Containment 为您提供了很大的灵活性和功能。
回答by matt.P
This wasn't part of your question, but you should consider using a UINavigationController
because it's probable that you will have to show new views from your MainViewController.
这不是您的问题的一部分,但您应该考虑使用 a,UINavigationController
因为您可能必须从MainViewController显示新视图。
The architecture I would use is the next:
我将使用的架构是下一个:
- UINavigationController
- LoginViewController (RootViewController)
- SignupViewController (Modal)
- MainViewController (Push)
- LoginViewController (RootViewController)
- 导航控制器
- 登录视图控制器(RootViewController)
- SignupViewController(模态)
- MainViewController(推送)
- 登录视图控制器(RootViewController)
So your first view controller is the LoginViewController.
所以你的第一个视图控制器是LoginViewController。
In your SignupViewController, you implements the next protocol:
在您的SignupViewController 中,您实现了下一个协议:
@class SignupViewController;
@protocol SignupViewControllerDelegate : NSObject
@required
- (void)signupViewController:(SignupViewController*)viewController didSignupWithData:(id)customData;
- (void)signupViewControllerDidCancel:(SignupViewController*)viewController;
@end
The customData
object is only useful if you need to pass data from your SignupViewControllerto your MainViewController.
该customData
对象仅在您需要将数据从SignupViewController 传递到MainViewController时才有用。
And you add this property to your SignupViewController
并且您将此属性添加到您的SignupViewController
@interface SignupViewController : UIViewController
@property (nonatomic, assign) id <SignupViewControllerDelegate> delegate;
...
@end
Your LoginViewControllernow has to implement the protocol you just created.
您的LoginViewController现在必须实现您刚刚创建的协议。
@interface LoginViewController : UIViewController <SignupViewControllerDelegate>
...
@end
And you should implement those methods like this
你应该像这样实现这些方法
@implementation LoginViewController
- (void)signupViewController:(SignupViewController*)viewController didSignupWithData:(id)customData {
// You can dismiss the SignUpViewController before pushing your next view
[self dismissViewControllerAnimated:NO completion:^{
// You can store the data you received from the SignupViewController
// Push your next view controller here
[self performSegueWithIdentifier:@"myIdentifier" sender:nil];
// Or this if you don't use Storyboard
MainViewController *vc = [[MainViewController alloc] initWithCustomData:customData];
[self.navigationController pushViewController:vc animated:YES];
}];
}
- (void)signupViewControllerDidCancel:(SignupViewController*)viewController {
// The user canceled the Signup operation, just dismiss the viewController
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
I'm explaining a little this code ^^ In your SignupViewController, when the user clicks on the button that ends the signup process, you call this method
我在解释一下这段代码 ^^ 在你的SignupViewController 中,当用户点击结束注册过程的按钮时,你调用这个方法
[self.delegate signupViewController:self didSignupWithData:myCustomData];
Or if he cancels
或者如果他取消
[self.delegate signupViewControllerDidCancel:self];
With this method, your SignupViewControllerwill be removed when you present your MainViewController. And when the user logouts, you will have to call this method in your MainViewController:
使用此方法,当您展示MainViewController时,您的SignupViewController将被删除。当用户注销时,您必须在MainViewController 中调用此方法:
[self.navigationController popViewControllerAnimated:YES];
As your SignupViewControlleris already dismissed, you will be redirected yo your LoginViewControllerdirectly.
由于您的SignupViewController已经被解除,您将被直接重定向到您的LoginViewController。
回答by user2387149
SOLUTION: Modifying the current navigation stack
解决方案:修改当前导航堆栈
The neatest way to solve this problem is by accessing the navigation controller Navigation stack. The navigation controller knows the flow by storing the controllers in an array where it stacks on an on the controllers. You can modify this stack by removing the undesired view controller once is safe to do so, this stack is represented on the property called viewControllers
(NSArray). The safe way is to remove it from the array after is not the current view controller (or the top one on the stack) which you can check by looking at the property visibleViewController
解决这个问题的最巧妙方法是访问导航控制器导航堆栈。导航控制器通过将控制器存储在一个数组中来了解流程,它堆叠在控制器上。您可以通过删除不需要的视图控制器来修改此堆栈,一旦这样做是安全的,此堆栈表示在称为viewControllers
(NSArray)的属性上。安全的方法是在不是当前视图控制器(或堆栈中的顶部控制器)之后将其从数组中删除,您可以通过查看属性来检查它visibleViewController
So your array should look like this when you already signedup and you are on the mainViewController:
[loginVC,SignUpVC,MainVC]
因此,当您已经注册并且您在 mainViewController 上时,您的数组应该如下所示:
[loginVC,SignUpVC,MainVC]
That means MainVC
is the visibleViewController
and it is safe to modify the navigation stack as long as you keep the same visibleViewController
as the last item on your array.
这意味着MainVC
是visibleViewController
,它是安全的修改导航堆栈,只要你保持相同visibleViewController
的阵列上的最后一个项目。
Since is not a Mutable Array just assign a new array to the viewControllers
property with this [loginVC,MainVC]
. I will recommend at least taking a peak to the documentation on UINavigationController.
由于不是可变数组,因此只需将新数组分配给viewControllers
具有 this的属性[loginVC,MainVC]
。我会建议至少在UINavigationController上的文档中找到一个高峰。
回答by poisondminds
This worked for me; it was extremely tedious getting the order correct.
这对我有用;让订单正确是非常乏味的。
DestinationViewController *vc = [[UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:@"DestinationView"];
UIViewController* presentingViewController = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^{
[presentingViewController presentViewController:vc animated:YES completion:nil];
}];