Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS - Split View Controller - How do I get a pointer (reference) to the Detail View Controller from inside the Master View Controller?

iOS - Split View Controller - How do I get a pointer (reference) to the Detail View Controller (the bigger right one) from inside the Master View Controller (the smaller left one)?

My gut tell me the Main Split View Controller should have a reference to Detail View Controller and to my own Master View Controller, but I can't figure out how to get it.

Any thoughts?

like image 640
unom Avatar asked Aug 18 '14 08:08

unom


People also ask

How do I load a view view controller?

Add views to your view controller To that root view, you add the custom views you need to present your interface. In storyboards, you add views by dragging them onto the view controller scene. For example, the following figure shows a view controller with an image view and button on an iPhone.

What is view controllers in iOS?

View controllers are the foundation of your app's internal structure. Every app has at least one view controller, and most apps have several. Each view controller manages a portion of your app's user interface as well as the interactions between that interface and the underlying data.

How does the splitviewcontroller property work?

The splitViewController property works by walking up the view controller hierarchy and trying to find any split view controller that the calling view controller is in. If the view controller is not in a split view controller, then the property is nil. It works the same as the navigationController and tabBarController view controller properties.

How do I get the Master View Controller in Split View?

A split view controller has an array property viewControllers which contains the master and detail view controllers. The master view controller, in your case, is actually a navigation controller. So to get the actual MasterViewController instance, you take the navigation controller’s first view controller.

What is the relationship between Master View Controller and detail view controller?

In the Master-Detail App template, the master view controller has a reference to the detail view controller. That means the master view controller can set a property on the detail view controller when a row gets selected. That works fine for simple applications where you only have one view controller in the detail pane.

How do I get the detail view controller in Xcode?

To get the detail view controller, you look at the second view controller in the viewControllers array of the split view controller. The download materials for this tutorial contain a folder called MonsterArt Drag this folder containing those images into Assets.xcassets in Xcode.


2 Answers

Split view controllers do have references to their master and detail view controllers, via the viewControllers property.

In iOS 7.x and below, the viewControllers array should have exactly two view controller objects in it. The first object is the master view controller and the second object is the detail view controller.

In iOS 8.0 and above, the viewControllers array has at least one view controller object in it – the master (or "primary") view controller. If a second view controller object is in the array, then it is the detail (or "secondary") view controller. When the split view controller is collapsed, only the master view controller is in this array, and when expanded it will contain both the master and the detail view controllers.

You can use the splitViewController property of all view controllers to get your split view controller, and from there use the viewControllers property to access either your master or detail view controllers, like so:

Swift:

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]; } 

The splitViewController property works by walking up the view controller hierarchy and trying to find any split view controller that the calling view controller is in. If the view controller is not in a split view controller, then the property is nil. It works the same as the navigationController and tabBarController view controller properties.

You can make the master and detail view controllers easier to access using an extension in Swift (or a category in Objective-C) on UISplitViewController, like so (replacing all the xx_'s with your own prefix if you're using Objective-C):

Swift:

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 

You can then make use of these properties like so:

Swift:

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"; } 
like image 156
TylerP Avatar answered Oct 23 '22 04:10

TylerP


If you are using iOS 14+, you can get a specific viewController from splitViewController using viewController(for:) method:

let detailViewController = splitViewController.viewController(for: .secondary) as? DetailViewController 
like image 40
pableiros Avatar answered Oct 23 '22 05:10

pableiros