访问模态视图控制器父级
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)
...
...
【讨论】:
以上是关于访问模态视图控制器父级的主要内容,如果未能解决你的问题,请参考以下文章
在模态视图控制器的解除动画时访问presentingViewController
从主视图控制器访问模态视图控制器中的 UITextField 中的文本