iOS – 拆分视图控制器 – 如何从主视图控制器中获取指向(详细视图控制器)的指针(引用)?

iOS – 分割视图控制器 – 如何从主视图控制器(较小的左侧)获取指向详细视图控制器(较大的右侧)的指针(引用)?

我的直觉告诉我主分割视图控制器应该有一个参考细节视图控制器和我自己的主视图控制器,但我不知道如何得到它。

有什么想法吗?

分割视图控制器通过viewControllers属性具有对主视图控制器和详细视图控制器的viewControllers

在iOS 7.x及以下版本中, viewControllers数组中应该只有两个视图控制器对象。 第一个对象是主视图控制器,第二个对象是详细视图控制器。

在iOS 8.0和更高版本中, viewControllers数组中至less有一个视图控制器对象 – 主视图控制器(或“主”视图控制器)。 如果第二个视图控制器对象在数组中,则它是详细(或“次”)视图控制器。 拆分视图控制器时,只有主视图控制器位于此数组中,展开时它将包含主视图控制器和详细视图控制器。

您可以使用所有视图控制器的splitViewController属性来获取您的分割视图控制器,然后使用viewControllers属性访问您的主视图控制器或详细视图控制器,如下所示:

迅速:

 let masterVC = self.splitViewController?.viewControllers.first let detailVC = (self.splitViewController?.viewControllers.count > 1) ? self.splitViewController?.viewControllers[1] : nil 

Objective-C的:

 UIViewController *masterVC = [self.splitViewController.viewControllers firstObject]; UIViewController *detailVC; if (self.splitViewController.viewControllers.count > 1) { detailVC = self.splitViewController.viewControllers[1]; } 

splitViewController属性的工作原理是遍历视图控制器层次结构,并尝试查找调用视图控制器所在的任何分割视图控制器。如果视图控制器不在分割视图控制器中,则该属性nil 。 它的作用与navigationControllertabBarController视图控制器属性相同。

你可以在UISplitViewController上使用Swift中的扩展(或Objective-C中的一个类)来更轻松地访问主视图控制器和详细视图控制器,就像这样(如果使用Objective-C,用你自己的前缀replace所有的xx_ ) ):

迅速:

 extension UISplitViewController { var primaryViewController: UIViewController? { return self.viewControllers.first } var secondaryViewController: UIViewController? { return self.viewControllers.count > 1 ? self.viewControllers[1] : nil } } 

Objective-C的:

 // UISplitViewController+ChildViewControllerAccess.h @interface UISplitViewController (ChildViewControllerAccess) @property (nonatomic, readonly) UIViewController *xx_primaryViewController; @property (nonatomic, readonly) UIViewController *xx_secondaryViewController; @end // UISplitViewController+ChildViewControllerAccess.m @implementation UISplitViewController (ChildViewControllerAccess) - (UIViewController *)xx_primaryViewController { return self.viewControllers.firstObject; } - (UIViewController *)xx_secondaryViewController { return self.viewControllers.count > 1 ? self.viewControllers[1] : nil; } @end 

然后你可以使用这些属性如下:

迅速:

 func someFunctionInSomeViewControllerClass { // Get the primary and secondary view controllers if // this view controller is in a split view controller. // These will be nil if this view controller is not a // descendant of a split view controller. var primaryVC = self.splitViewController?.primaryViewController var secondaryVC = self.splitViewController?.secondaryViewController // Do something with them primaryVC?.title = "This is the primary VC" secondaryVC?.title = "This is the secondary VC" } 

Objective-C的:

 #import "UISplitViewController+ChildViewControllerAccess.h" [...] - (void)someMethodInSomeViewControllerClass { // Get the primary and secondary view controllers if // this view controller is in a split view controller. // These will be nil if this view controller is not a // descendant of a split view controller. UIViewController *primaryVC = self.splitViewController.xx_primaryViewController; UIViewController *secondaryVC = self.splitViewController.xx_secondaryViewController; // Do something with them primaryVC.title = @"This is the primary VC"; secondaryVC.title = @"This is the secondary VC"; } 

在您的UISplitViewController子类中创build一个属性:

 var _detailViewController: UIViewController? { get { if viewControllers.count > 1 { return viewControllers[1] as? UIViewController } return nil } } 

根据苹果的文档,这有时应该返回零,但根据我的经验,它总是返回细节视图控制器,无论状态。

此外,不要调用这个属性“detailViewController”而不是“_detailViewController” – 苹果显然已经在引擎盖下使用了这个名字,并且会让你的用户界面变得混乱。

UISplitViewController真的很高兴,需要大量的清理和纠正文档…