我目前有3个ViewControllers:LoginViewController
,SignUpViewController
和MainViewController
。
当用户打开应用时,系统会显示LoginViewController
。如果用户第一次使用该应用,那么他们必须注册,“注册”按钮位于LoginViewController
。 “注册”按钮将显示SignUpViewController
。
用户完成注册后。将显示MainViewController
。
我想做的是。在MainViewController
中会有一个“注销”按钮。当用户按下它时,MainViewController
应该被解雇,LoginViewController
应该在那里。用户不应该第二次看到SignUpViewController
。
以下是我的尝试:
1)在“注册”按钮中解除SignUpViewController
并显示MainViewController
:
- (void) signUpClicked
{
MainViewController *mainViewController = [viewController.storyboard instantiateViewControllerWithIdentifier:@"MainViewController"];
[viewController presentViewController:mainViewController animated:YES completion:^{
[viewController dismissViewControllerAnimated:NO completion:^{
}];
}];
}
2)加载MainViewController
时,取消SignUpViewController
- (void)viewDidLoad
{
[super viewDidLoad];
SignUpViewController *signUpViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SignUpViewController"];
[signUpViewController dismissViewControllerAnimated:NO completion:^{
}];
}
答案 0 :(得分:5)
知道了。我将SignUpViewController传递给MainViewController并解除了MainViewController中的SignUpViewController。
对于其他与我有同样问题的人。
<强> SignUpViewController.m 强>
- (void) signUpButtonClicked
{
MainViewController *mainViewController = [viewController.storyboard instantiateViewControllerWithIdentifier:@"MainViewController"];
mainViewController.signUpViewController = viewController;
[viewController presentViewController:mainViewController animated:YES completion:^{
}];
}
<强> MainViewController.m 强>
- (IBAction)logoutClicked:(id)sender
{
[self dismissViewControllerAnimated:YES completion:^{
[self.signUpViewController dismissViewControllerAnimated:NO completion:^{
}];
}];
}
答案 1 :(得分:1)
presentViewController可以帮到你很长的路,但也许你应该推出自己的容器视图控制器。他们很容易接受! UIViewController上的UIContainerViewControllerProtectedMethods类别概述了您可以/应该使用的方法。
基本要点是你有一个容器View Controller,它将子视图控制器添加到自身,并将它们的视图添加为自己视图的子视图。解决繁重问题的主要方法是:
... transitionFromViewController:(UIViewController *)fromViewController
toViewController:(UIViewController *)toViewController
duration:(NSTimeInterval)duration
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion
在动画部分,您可以进行任何想要的动作。在您的情况下,您可能希望将LoginViewController视图放在MainViewController的视图后面,并将MainViewController的视图移到屏幕外。您可以提供自己的动画选项,因此外观将与dismissViewController现在的外观类似。
设置会增加一些开销,但View Controller Containment为您提供了很大的灵活性和强大功能。
答案 2 :(得分:1)
这不是您问题的一部分,但您应该考虑使用UINavigationController
,因为您很可能必须从 MainViewController 中显示新观看次数
我将使用的架构是下一个:
所以你的第一个视图控制器是 LoginViewController 。
在 SignupViewController 中,您实现了下一个协议:
@class SignupViewController;
@protocol SignupViewControllerDelegate : NSObject
@required
- (void)signupViewController:(SignupViewController*)viewController didSignupWithData:(id)customData;
- (void)signupViewControllerDidCancel:(SignupViewController*)viewController;
@end
customData
对象仅在您需要将数据从 SignupViewController 传递到 MainViewController 时才有用。
然后将此属性添加到 SignupViewController
@interface SignupViewController : UIViewController
@property (nonatomic, assign) id <SignupViewControllerDelegate> delegate;
...
@end
您的 LoginViewController 现在必须实现您刚刚创建的协议。
@interface LoginViewController : UIViewController <SignupViewControllerDelegate>
...
@end
你应该实现这样的方法
@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
我正在解释这个代码^^ 在 SignupViewController 中,当用户点击结束注册过程的按钮时,您调用此方法
[self.delegate signupViewController:self didSignupWithData:myCustomData];
或者如果他取消
[self.delegate signupViewControllerDidCancel:self];
使用此方法,当您展示 MainViewController 时, SignupViewController 将被删除。当用户注销时,您必须在 MainViewController 中调用此方法:
[self.navigationController popViewControllerAnimated:YES];
由于 SignupViewController 已被解散,您将直接重定向到 LoginViewController 。
答案 3 :(得分:1)
解决方案:修改当前导航堆栈
解决此问题的最佳方法是访问导航控制器导航堆栈。导航控制器通过将控制器存储在控制器上堆叠的阵列中来了解流程。一旦安全,可以通过删除不需要的视图控制器来修改此堆栈,此堆栈在名为viewControllers
的属性(NSArray)上表示。安全的方法是在不是当前视图控制器(或堆栈顶部的控制器)之后将其从数组中删除,您可以通过查看属性visibleViewController
所以当你已经signedup并且你在mainViewController上时,你的数组应该是这样的:
[loginVC,SignUpVC,MainVC]
这意味着MainVC
是visibleViewController
,只要您保持与数组中最后一项相同的visibleViewController
,就可以安全地修改导航堆栈。
由于不是可变数组,只需使用此viewControllers
为[loginVC,MainVC]
属性分配一个新数组。我建议至少在UINavigationController上的文档中找到一个高峰。
答案 4 :(得分:0)
这对我有用;订单是否正确非常繁琐。
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];
}];