访问模态视图控制器父级

Posted

技术标签:

【中文标题】访问模态视图控制器父级【英文标题】:Access modal view controller parent 【发布时间】:2011-07-18 15:16:01 【问题描述】:

我正在模态地展示一个 ViewController。 如何访问父视图控制器?

我的架构是 TabBarController=>VC1=>VC2=>VC3=>MVC1,我想从 MVC1 到达 VC3。

在 VC3 中,我有这个代码:

- (void) editAd
    AskPasswordViewController *modalViewController = [[AskPasswordViewController alloc] initWithNibName:@"AskPasswordView" bundle:nil];

    NSLog(@"modalparent class=%@", [[modalViewController parentViewController] class]);

    [self presentModalViewController:modalViewController animated:YES];
    [modalViewController release];

我在 MVC1 中试过这个:

- (void) sendRequest 
    NSLog(@"classe : %@",[[self parentViewController] class] );

但它会返回我的 TabBarViewController...

【问题讨论】:

【参考方案1】:

您可以通过调用访问父级:

self.presentingViewController

根据苹果文档:

呈现此视图控制器(或其 最远的祖先。)

【讨论】:

虽然其他 cmets 在他们的时代是正确的,但我认为这是使用故事板的方式(尤其是从 ios 7 开始) 仅供参考,这在 viewDidLoad 中将为零【参考方案2】:

我会做这样的事情的方式是简单地创建一个委托。在AskPasswordViewController的头部,放

id delegate;

@property (nonatomic, assign) id delegate;

在实现文件中综合它。然后在你分配/初始化模态控制器之后,在你展示它之前,设置modalViewController.delegate = self;。然后在模态控制器中,您可以调用self.delegate 从呈现它的视图控制器中获取信息。我希望这会有所帮助

【讨论】:

谢谢。这就是我最终所做的。但我想了解为什么父视图控制器是标签栏。看起来真的很奇怪,我害怕在某个地方做错了什么。 我不完全确定为什么,但我的理论是,由于您正在呈现一个模态视图,它不一定是呈现它的视图控制器的子视图,而是它的一部分。因此,它的父级是将其作为扩展呈现的视图的父级。它似乎在这方面有不同的行为,而不是通过导航控制器推送视图 它也对我有用。但我不得不让类“parentviewcontroller”的代表。我想访问“parentviewcontroller”的uitabbar。 值得指出的是,这是 Apple 官方推荐的解决此问题的方法,详见此处的“呈现“视图控制器并选择过渡样式”部分:developer.apple.com/library/ios/#featuredarticles/…【参考方案3】:

您总是可以通过像这样调用 parentViewController 来进一步返回:

self.parentViewController.parentViewController .... 以此类推,直到找到正确的。

【讨论】:

我有一个tabbar,它展示了navigationController,它推送了一些viewcontroller,它展示了烦人的viewController。 在你的问题中给我们一个反馈,就像告诉我们你 modalviewcontroller archtecture vc1 -> vc2 -> nvc -> tbvc 然后告诉我们你想从哪里到哪里去。 要打印实际的类名,请使用:NSLog(@"clase : %@",NSStringFromClass[[self parentViewController] class]) ); 从 MVC1 调用 self.parentViewController 应该没问题。它将达到 VC3。【参考方案4】:

Vibhor Goyal 的补充 - 有时,self.presentingViewController 注册为 NavigationController。因此尝试:

if let vc = self.presentingViewController.childViewControllers.last as? YourViewController 
// do stuff here

【讨论】:

【参考方案5】:

在这里,我想出了从任何地方导航到根目录的通用方法。

    您使用该类创建一个新的 Class 文件,以便可以从项目中的任何位置访问它:

    import UIKit
    
    class SharedControllers
    
        static func navigateToRoot(viewController: UIViewController)
        
            var nc = viewController.navigationController
    
            // If this is a normal view with NavigationController, then we just pop to root.
            if nc != nil
            
                nc?.popToRootViewControllerAnimated(true)
                return
            
    
            // Most likely we are in Modal view, so we will need to search for a view with NavigationController.
            let vc = viewController.presentingViewController
    
            if nc == nil
            
                nc = viewController.presentingViewController?.navigationController
            
    
            if nc == nil
            
                nc = viewController.parentViewController?.navigationController
            
    
            if vc is UINavigationController && nc == nil
            
                nc = vc as? UINavigationController
            
    
            if nc != nil
            
                viewController.dismissViewControllerAnimated(false, completion:
                    
                        nc?.popToRootViewControllerAnimated(true)
                )
            
        
    
    

    在项目中的任何地方使用:

    
        ...
        SharedControllers.navigateToRoot(self)
        ...
    
    

【讨论】:

这是不好的做法!【参考方案6】:
//You have to get the root, iterate through the root's ViewControllers and then ask for the ParentViewController.
    UINavigationController ​*root = (UINavigationController*​)[[(AppDelegate*) [[UIApplication sharedApplication]delegate] window] rootViewController];
           for (UIViewController *VC in root.viewControllers) 
               if([VC isKindOfClass:[YourParentViewController class]])
                   YourParentViewController*  parent = (YourParentViewController*)VC;
                   [parent callMethod]; // your code here
                   [self dismissViewControllerAnimated:YES completion:nil];
               
           

【讨论】:

【参考方案7】:

如果presentingViewController 给了你意想不到的结果,而你又不想摆弄它,那就这样做吧:

class MyViewController: UIViewController 

    private weak var presenter: UIViewController?

    init(presenter: UIViewController) 
        self.presenter = presenter
        super.init(nibName: nil, bundle: nil)
        ...
    
    
    ...

【讨论】:

以上是关于访问模态视图控制器父级的主要内容,如果未能解决你的问题,请参考以下文章

UIView 旋转,模态视图横向和纵向,父级无法渲染

模态视图控制器使背景变黑

在模态视图控制器的解除动画时访问presentingViewController

从主视图控制器访问模态视图控制器中的 UITextField 中的文本

在嵌套环境中点击 childviewcontroller 中的单元格访问父级父级视图控制器的 tableview 委托

使用自定义转换旋转模态 UIViewController