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

falq053o  于 2024-01-09  发布在  iOS
关注(0)|答案(3)|浏览(173)

iOS -拆分视图控制器-如何从主视图控制器(较小的左视图控制器)内部获取指向细节视图控制器(较大的右视图控制器)的指针(引用)?
我的直觉告诉我,主分割视图控制器应该有一个参考细节视图控制器和我自己的主视图控制器,但我不知道如何得到它。
有什么想法吗?

whlutmcx

whlutmcx1#

通过viewControllers属性,拆分视图控制器 * 确实 * 有对它们的主视图控制器和细节视图控制器的引用。
在iOS 7.x及更低版本中,viewControllers数组中应该正好有两个视图控制器对象。第一个对象是主视图控制器,第二个对象是详细视图控制器。
在iOS 8.0及更高版本中,viewControllers数组中至少有一个视图控制器对象-master如果第二个视图控制器对象在数组中,那么它就是详细视图控制器。当拆分视图控制器被折叠时,只有主视图控制器在该阵列中,并且当扩展时,它将包含主视图控制器和细节视图控制器。
您可以使用所有视图控制器的splitViewController属性来获取拆分视图控制器,然后使用viewControllers属性来访问主视图控制器或详细视图控制器,如下所示:

Swift:

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

字符串

-C:

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


splitViewController属性的工作原理是沿着视图控制器层次结构向上走,并尝试查找调用视图控制器所在的任何拆分视图控制器。如果视图控制器不在拆分视图控制器中,则属性为nil。它的工作原理与navigationControllertabBarController视图控制器属性相同。
你可以在UISplitViewController上使用Swift中的一个扩展(或者在xx_中使用一个category)来使master和detail view controllers更容易访问,就像这样(如果你使用的是xx_,请用你自己的前缀替换所有的xx_):

Swift:

  1. extension UISplitViewController {
  2. var primaryViewController: UIViewController? {
  3. return self.viewControllers.first
  4. }
  5. var secondaryViewController: UIViewController? {
  6. return self.viewControllers.count > 1 ? self.viewControllers[1] : nil
  7. }
  8. }

-C:

  1. // UISplitViewController+ChildViewControllerAccess.h
  2. @interface UISplitViewController (ChildViewControllerAccess)
  3. @property (nonatomic, readonly) UIViewController *xx_primaryViewController;
  4. @property (nonatomic, readonly) UIViewController *xx_secondaryViewController;
  5. @end
  6. // UISplitViewController+ChildViewControllerAccess.m
  7. @implementation UISplitViewController (ChildViewControllerAccess)
  8. - (UIViewController *)xx_primaryViewController
  9. {
  10. return self.viewControllers.firstObject;
  11. }
  12. - (UIViewController *)xx_secondaryViewController
  13. {
  14. return self.viewControllers.count > 1 ? self.viewControllers[1] : nil;
  15. }
  16. @end


然后你可以像这样使用这些属性:

Swift:

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

-C:

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

展开查看全部
r9f1avp5

r9f1avp52#

如果你使用的是iOS 14+,你可以使用viewController(for:)方法从splitViewController中获取一个特定的viewController

  1. let detailViewController = splitViewController.viewController(for: .secondary) as? DetailViewController

字符串

mfuanj7w

mfuanj7w3#

在UISplitViewController子类中创建一个属性:

  1. var __detailViewController: UIViewController? {
  2. get {
  3. if viewControllers.count > 1 {
  4. return viewControllers[1] as? UIViewController
  5. }
  6. return nil
  7. }
  8. }

字符串
根据Apple的文档,这有时应该返回nil,但根据我的经验,它总是返回详细视图控制器,而不管状态如何。
另外,不要将此属性称为“detailViewController”而不是“__detailViewController”- Apple显然已经在幕后使用该名称,它会扰乱您的UI。
UISplitViewController是真的hokey和需要大量的清理和纠正的文档.

相关问题