iOS -拆分视图控制器-如何从主视图控制器(较小的左视图控制器)内部获取指向细节视图控制器(较大的右视图控制器)的指针(引用)?我的直觉告诉我,主分割视图控制器应该有一个参考细节视图控制器和我自己的主视图控制器,但我不知道如何得到它。有什么想法吗?
whlutmcx1#
通过viewControllers属性,拆分视图控制器 * 确实 * 有对它们的主视图控制器和细节视图控制器的引用。在iOS 7.x及更低版本中,viewControllers数组中应该正好有两个视图控制器对象。第一个对象是主视图控制器,第二个对象是详细视图控制器。在iOS 8.0及更高版本中,viewControllers数组中至少有一个视图控制器对象-master如果第二个视图控制器对象在数组中,那么它就是详细视图控制器。当拆分视图控制器被折叠时,只有主视图控制器在该阵列中,并且当扩展时,它将包含主视图控制器和细节视图控制器。您可以使用所有视图控制器的splitViewController属性来获取拆分视图控制器,然后使用viewControllers属性来访问主视图控制器或详细视图控制器,如下所示:
viewControllers
splitViewController
Swift:
let masterVC = self.splitViewController?.viewControllers.firstlet detailVC = (self.splitViewController?.viewControllers.count > 1) ? self.splitViewController?.viewControllers[1] : nil
let masterVC = self.splitViewController?.viewControllers.first
let detailVC = (self.splitViewController?.viewControllers.count > 1) ? self.splitViewController?.viewControllers[1] : nil
字符串
-C:
UIViewController *masterVC = [self.splitViewController.viewControllers firstObject];UIViewController *detailVC;if (self.splitViewController.viewControllers.count > 1) { detailVC = self.splitViewController.viewControllers[1];}
UIViewController *masterVC = [self.splitViewController.viewControllers firstObject];
UIViewController *detailVC;
if (self.splitViewController.viewControllers.count > 1) {
detailVC = self.splitViewController.viewControllers[1];
}
型splitViewController属性的工作原理是沿着视图控制器层次结构向上走,并尝试查找调用视图控制器所在的任何拆分视图控制器。如果视图控制器不在拆分视图控制器中,则属性为nil。它的工作原理与navigationController和tabBarController视图控制器属性相同。你可以在UISplitViewController上使用Swift中的一个扩展(或者在xx_中使用一个category)来使master和detail view controllers更容易访问,就像这样(如果你使用的是xx_,请用你自己的前缀替换所有的xx_):
nil
navigationController
tabBarController
UISplitViewController
xx_
extension UISplitViewController { var primaryViewController: UIViewController? { return self.viewControllers.first } var secondaryViewController: UIViewController? { return self.viewControllers.count > 1 ? self.viewControllers[1] : nil }}
extension UISplitViewController {
var primaryViewController: UIViewController? {
return self.viewControllers.first
var secondaryViewController: UIViewController? {
return self.viewControllers.count > 1 ? self.viewControllers[1] : nil
型
// 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
// 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;
型然后你可以像这样使用这些属性:
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"}
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"
#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";}
#import "UISplitViewController+ChildViewControllerAccess.h"
[...]
- (void)someMethodInSomeViewControllerClass
UIViewController *primaryVC = self.splitViewController.xx_primaryViewController;
UIViewController *secondaryVC = self.splitViewController.xx_secondaryViewController;
primaryVC.title = @"This is the primary VC";
secondaryVC.title = @"This is the secondary VC";
r9f1avp52#
如果你使用的是iOS 14+,你可以使用viewController(for:)方法从splitViewController中获取一个特定的viewController:
iOS 14+
viewController(for:)
viewController
let detailViewController = splitViewController.viewController(for: .secondary) as? DetailViewController
mfuanj7w3#
在UISplitViewController子类中创建一个属性:
var __detailViewController: UIViewController? { get { if viewControllers.count > 1 { return viewControllers[1] as? UIViewController } return nil }}
var __detailViewController: UIViewController? {
get {
if viewControllers.count > 1 {
return viewControllers[1] as? UIViewController
return nil
字符串根据Apple的文档,这有时应该返回nil,但根据我的经验,它总是返回详细视图控制器,而不管状态如何。另外,不要将此属性称为“detailViewController”而不是“__detailViewController”- Apple显然已经在幕后使用该名称,它会扰乱您的UI。UISplitViewController是真的hokey和需要大量的清理和纠正的文档.
3条答案
按热度按时间whlutmcx1#
通过
viewControllers
属性,拆分视图控制器 * 确实 * 有对它们的主视图控制器和细节视图控制器的引用。在iOS 7.x及更低版本中,
viewControllers
数组中应该正好有两个视图控制器对象。第一个对象是主视图控制器,第二个对象是详细视图控制器。在iOS 8.0及更高版本中,
viewControllers
数组中至少有一个视图控制器对象-master如果第二个视图控制器对象在数组中,那么它就是详细视图控制器。当拆分视图控制器被折叠时,只有主视图控制器在该阵列中,并且当扩展时,它将包含主视图控制器和细节视图控制器。您可以使用所有视图控制器的
splitViewController
属性来获取拆分视图控制器,然后使用viewControllers
属性来访问主视图控制器或详细视图控制器,如下所示:Swift:
字符串
-C:
型
splitViewController
属性的工作原理是沿着视图控制器层次结构向上走,并尝试查找调用视图控制器所在的任何拆分视图控制器。如果视图控制器不在拆分视图控制器中,则属性为nil
。它的工作原理与navigationController
和tabBarController
视图控制器属性相同。你可以在
UISplitViewController
上使用Swift中的一个扩展(或者在xx_
中使用一个category)来使master和detail view controllers更容易访问,就像这样(如果你使用的是xx_
,请用你自己的前缀替换所有的xx_
):Swift:
型
-C:
型
然后你可以像这样使用这些属性:
Swift:
型
-C:
型
r9f1avp52#
如果你使用的是
iOS 14+
,你可以使用viewController(for:)
方法从splitViewController
中获取一个特定的viewController
:字符串
mfuanj7w3#
在UISplitViewController子类中创建一个属性:
字符串
根据Apple的文档,这有时应该返回nil,但根据我的经验,它总是返回详细视图控制器,而不管状态如何。
另外,不要将此属性称为“detailViewController”而不是“__detailViewController”- Apple显然已经在幕后使用该名称,它会扰乱您的UI。
UISplitViewController是真的hokey和需要大量的清理和纠正的文档.