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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 05:21:45  来源:igfitidea点击:

Dismiss previous modal view controller in current view controller

iosobjective-cxcodeios7uiviewcontroller

提问by tnylee

I currently have 3 ViewControllers: LoginViewController, SignUpViewControllerand MainViewController.

我目前有 3 个 ViewControllers: LoginViewController,SignUpViewControllerMainViewController.

When the user opens the app, LoginViewControllerwill 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 MainViewControllerwill be presented.

一旦用户完成注册。在MainViewController将提交。

What I am trying to do is. In the MainViewControllerthere will be a "Log Out" button. When the user press it the MainViewControllershould be dismissed and LoginViewControllershould be there. The user should not see the SignUpViewControllerfor the second time.

我正在尝试做的是。在MainViewController将有“注销”按钮。当用户按下它时,MainViewController应该被解雇并且LoginViewController应该在那里。用户不应SignUpViewController第二次看到。

Here is what I have tried:

这是我尝试过的:

1) Dismiss SignUpViewControllerand present MainViewControllerin "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 MainViewControllerloads, 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 UINavigationControllerbecause 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)
  • 导航控制器
    • 登录视图控制器(RootViewController)
      • SignupViewController(模态)
    • MainViewController(推送)

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 customDataobject 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 MainVCis the visibleViewControllerand it is safe to modify the navigation stack as long as you keep the same visibleViewControlleras the last item on your array.

这意味着MainVCvisibleViewController,它是安全的修改导航堆栈,只要你保持相同visibleViewController的阵列上的最后一个项目。

Since is not a Mutable Array just assign a new array to the viewControllersproperty 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];

}];