【问题标题】:Hide all modal view controllers隐藏所有模态视图控制器
【发布时间】:2011-12-29 18:45:57
【问题描述】:

我有一个显示为 ModelViewController 的登录视图,我有一个显示为 NavigationControlloer 的注册视图:

登录(模型视图控制器) ---->注册(导航控制器)

我在 Loginview 中显示注册视图(CreateAccount),如下所示:

createAccount= [[CreateAccount alloc] initWithNibName:@"CreateAccount" bundle:nil];

navController = [[UINavigationController alloc] initWithRootViewController:createAccount];

UIBarButtonItem *cancelButtun=[[UIBarButtonItem alloc]initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(HideMe)];

UIBarButtonItem *registerButtun=[[UIBarButtonItem alloc]initWithTitle:@"Register" style:UIBarButtonItemStyleBordered target:self action:@selector(Register)];

createAccount.navigationItem.leftBarButtonItem = cancelButtun;
createAccount.navigationItem.rightBarButtonItem=registerButtun;
createAccount.title=@"Create Account";

[self presentModalViewController:navController animated:YES];

登录控制器有 NSURLConnectionDelegate 用于登录和注册。 注册完成后,我只需调用

[self dismissModalViewControllerAnimated:YES];

这将只关闭注册视图。

我还想关闭登录视图,以便返回主应用程序。

【问题讨论】:

  • 请说明您是如何呈现注册视图的。是另一种模态视图吗?

标签: iphone ios objective-c cocoa-touch modalviewcontroller


【解决方案1】:

调用dismissModalViewController 将,如果当前视图控制器没有呈现任何模态控制器,则改为调用其父级的方法。在视图控制器上调用该方法会将所有呈现的模式视图控制器关闭到该控制器。举例说明:

如果您有三个视图控制器:vc1、vc2 和 vc3,而 vc1 是主要/当前使用的视图控制器。

  1. 在 vc1 中,您呈现模态 vc2。然后在 vc2 中调用dismiss,因为没有从 vc2 呈现的模态 vcs,dismiss 消息被传递给关闭 vc2 的父级 (vc1),然后您回到 vc1。

  2. 在 vc1 中呈现模态 vc2,然后从 vc2 呈现模态 vc3。在 vc3 中调用dismiss 会将消息发送到其父级 (vc2),后者将关闭 vc3。要同时关闭 vc2 和 vc3,您需要在 vc1 中调用 dismiss,这将关闭所有(两​​个)模态视图控制器。如果关闭动画,则只有第一个动画。

解决此问题的最佳方法之一是完全使用导航控制器。即,最初不是使用 modalViews 来呈现登录视图,而是使用 navigationViewcontroller 本身。如果您需要出示注册页面。推动那个观点。如果您需要转到初始视图(即除了 loginView 或registrationView),则使用navigationViewcontroller 中的popToRootViewControllerAnimated 方法。

【讨论】:

    【解决方案2】:

    在这里查看我对类似问题的回答:Dismissing ModalViewController of ModalViewController

    我在我的应用程序中使用与您几乎相同的东西,这个解决方案对我有用。请务必同时阅读 cmets,因为其中一个参考随着 iOS5 发生了变化。

    编辑: 为了关闭显示在另一个模态视图上的模态视图,您必须在父级的父级上调用dismissModalViewControllerAnimated:。

    iOS

    [[[self parentViewController] parentViewController] dismissModalViewControllerAnimated:YES];
    

    iOS 5.0+(必须将所有对 parentViewController 的引用更改为 presentingViewController)

    [[[self presentingViewController] presentingViewController] dismissModalViewControllerAnimated:YES];
    

    【讨论】:

    • +1 这对我来说效果很好。如果解决方案也包含在这里,那就太好了。
    • 小心:dismissModalViewControllerAnimated 已弃用(在 iOS 6.0 中),请改用 dismissViewControllerAnimated:completion:
    【解决方案3】:

    目前的主要问题是登录视图控制器完全不知道注册视图何时被关闭,我们可以通过委托来处理。

    首先在注册视图控制器上声明一个协议和一个委托属性。

    @protocol CreateAccountDelegate;
    
    @interface CreateAccount : UIViewController
    
    @property (nonatomic, assign) id <CreateAccountDelegate> delegate;
    
    @end
    
    @protocol CreateAccountDelegate <NSObject>
    
    - (void)createAccountViewControllerDidFinish:(CreateAccount *)controller;
    
    @end
    

    接下来,让登录视图控制器成为注册控制器的委托。

    createAccount = [[CreateAccount alloc] initWithNibName:@"CreateAccount" bundle:nil];
    createAccount.delegate = self;
    

    并实现-createAccountViewControllerDidFinish:

    - (void)createAccountViewControllerDidFinish:(CreateAccount *)controller
    {
        [self dismissModalViewControllerAnimated:YES];
    }
    

    最后,当您从注册控制器中解雇时,如果您即将解雇,请向代表发送消息通知它。

    [self.delegate createAccountViewControllerDidFinish:self];
    [self dismissModalViewControllerAnimated:YES];
    

    现在,说了这么多。我可以建议对您的设计进行更改吗?我将从一开始就将登录视图控制器作为导航控制器的一部分。然后,如果用户选择注册,只需将注册视图推送到控制器。这样,无论你从哪里解散,它只需要解散主导航控制器。

    【讨论】:

      【解决方案4】:

      dismissModalViewControllerAnimated: 关闭所有显示在发送者之上的模态视图控制器。要关闭返回到显示登录控制器的视图控制器,请保留对它的引用并按如下方式关闭:

      [loginController dismissModalViewController:animated]
      

      这是蛮力的做法。在我做类似事情的应用程序中,我发布了与会话(例如登录)状态相对应的各种通知,我的登录控制器观察这些通知并适当地关闭自己。

      【讨论】:

        【解决方案5】:

        将此方法放在您的应用程序委托中,它将删除所有具有 presentViewController 的视图控制器,这意味着它们是以模态方式呈现的

        -(void)dismissModalViews
        {
            if (self.window.rootViewController.presentedViewController) {
                [self.window.rootViewController.presentedViewController dismissViewControllerAnimated:NO completion:nil];
                [self performSelector:@selector(dismissModalViews) withObject:nil afterDelay:0.5];
            }
        }
        

        【讨论】:

        • 那么你有另一个问题,刚刚在开发目标设置为 7.0 的 xcode 中进行了测试,它仍然有效。确保您在实现 UIApplicationDelegate 协议的 NSObject 中调用此方法,并且您已设置 self.window.rootViewController。我没有按项目使用情节提要
        • 我将延迟更改为 0.75,然后它起作用了。我为 iOS 7 编译了一个 iOS 6 应用程序。也许他们改变了时间,因为在此之前它使用 0.5 时间。
        【解决方案6】:
        [[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissViewControllerAnimated:true completion:nil];
        

        关闭除 RootViewController 之外的所有控制器..

        【讨论】:

          【解决方案7】:
          while(self.presentedViewController)
                  [self.presentedViewController dismissViewControllerAnimated:NO completion:nil];
          

          在 iOS 7 中努力消除所有问题

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-05-01
            • 2017-06-23
            • 1970-01-01
            • 1970-01-01
            • 2017-11-14
            • 2013-01-11
            • 2013-06-13
            • 1970-01-01
            相关资源
            最近更新 更多