Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect when both the master and detail view controller are on screen?

I have implemented a UISplitViewController using a Universal Storyboard in Xcode 6. UISplitViewController is supported on iPhone running iOS 8 now, and by default only one view controller will be on screen at a time.

I need to know when both the master and detail view controllers are both on screen (iPad). I need to remove the disclosure indicators from UITableViewCells in the case both are on screen - only render them when only the master view controller is on screen (iPhone), just like the Settings app.

I could simply detect the device and only add them if it's an iPhone, but that's not recommended. It's possible a new device would display only one view controller and not identify as a phone. Another thought would be to detect if self.splitViewController is nil, but that won't work because it won't be nil on iPhone nor iPad because it actually is in a split view controller on iPhone.

Is it possible to detect when both the master and detail view controller are visible on screen at the same time?

like image 394
Jordan H Avatar asked Aug 21 '14 21:08

Jordan H


3 Answers

UISplitViewController

@property(nonatomic, readonly, getter=isCollapsed) BOOL collapsed

This property is set to YES when the split view controller content is semantically collapsed into a single container. Collapsing happens when the split view controller transitions from a horizontally regular to a horizontally compact environment. After it has been collapsed, the split view controller reports having only one child view controller in its viewControllers property. The other view controller is collapsed into the other view controller’s content with the help of the delegate object or discarded temporarily. When collapsed, the displayMode property has no impact on the appearance of the split view controller interface.

The value of this property is NO when the split view controller is capable of displaying both of its child view controllers at the same time, even if it is not showing them both at the moment. In this expanded mode, the split view controller’s configuration of its child view controllers is determined by the displayMode property. In addition, the viewControllers property contains both the primary and secondary view controllers.

During a transition from an expanded to collapsed interface, the value of this property is NO until after the collapse transition finishes and all of the relevant delegate methods have been called. Similarly, when transitioning back to an expanded interface, the value is YES until the transition finishes.

from class reference.

Thanks to Frederik A. Winkelsdorf:

It should be noted that .collapsed also reports false if a DetailViewController is zoomed to cover the full screen. If you really want to know if both are visible, check beside the .collapsed property for splitViewController.displayMode == UISplitViewControllerDisplayMode.AllVisible. I found it useful when dealing with iPhone 6 Plus Landscape layouts.

like image 177
Schemetrical Avatar answered Nov 07 '22 04:11

Schemetrical


This is the way to check Displaymode for UISplitViewController

- (void)splitViewController:(UISplitViewController *)splitViewController willChangeToDisplayMode:(UISplitViewControllerDisplayMode)displayMode {
  if (displayMode == UISplitViewControllerDisplayModePrimaryHidden) {
       NSLog(@"Detail view is visible");
} else if (displayMode == UISplitViewControllerDisplayModeAllVisible) {
       NSLog(@"both are visible");
  }
}
like image 36
Nagarjun Avatar answered Nov 07 '22 03:11

Nagarjun


In swift:

func splitViewController(_ svc: UISplitViewController, willChangeTo displayMode: UISplitViewController.DisplayMode) {

if displayMode == .primaryHidden {
        print("Detail is visible")
    }
if displayMode == .allVisible {
        print("Master and Detail are visible")
    }
}
like image 1
Miguel Herrero Avatar answered Nov 07 '22 05:11

Miguel Herrero