Change the Width of Master View in Split View Controller

How do you change the width of the master view in a Split View Controller?

The side-by-side mode of a UISplitViewController shows both master and detail view controllers onscreen at the same time. You can see an example of this below taken from my WorldFacts example code running in portrait on an iPad Air.

If you look carefully you will notice that the master view is too narrow and truncates the country name for the “Democratic Republic of the Congo”. The UISplitViewController sets the width of the master view but by default has a maximum width of 320 points.

Primary Column Width

The UISplitViewController class has three new properties available from iOS 8 that allow you to set the width of the master view:

preferredPrimaryColumnWidthFraction: A CGFloat between 0.0 and 1.0 that sets the preferred width of the primary (master) column as a percentage of the width of the split view controller. The values of minimumPrimaryColumnWidth and maximumPrimaryColumnWidth limit the actual width of the master view.

minimumPrimaryColumnWidth: A CGFloat for the minimum width in points of the master view content. Default value of UISplitViewControllerAutomaticDimension sets a minimum width of 0 points.

maximumPrimaryColumnWidth: A CGFloat for the maximum width in points of the master view content. Default value of UISplitViewControllerAutomaticDimension sets a maximum width of 320 points.

The above properties are also animatable if you need to change them at runtime. If you need the actual width of the master view there is a read-only property primaryColumnWidth.

Setting the Width of the Master View

My first thoughts were to set the width of the master view to be 50% of the split view controller width. In my example project I can do this when configuring the split view controller in the Application Delegate:

splitViewController.preferredPrimaryColumnWidthFraction = 0.5;

Remember that the value of maximumPrimaryColumnWidth limits the actual width of the view and has a default value of 320 points. An iPad has a width of 768 points in portrait and 1024 points in landscape. Either way 50% of our screen width exceeds the maximum primary column width so we need to increase the maximum value. In this case I set it to the full width of the split view which is large enough for either orientation.

splitViewController.maximumPrimaryColumnWidth = splitViewController.view.bounds.size.width;

The screenshot below shows the appearance of the split view controller in portrait with the master and detail views now each using 50% of the screen width:

Unfortunately a setting of 50% makes the master view look a little too large in landscape mode:

A better approach to deal with the original problem with a master view that was too narrow is to leave the fraction property alone and adjust the minimum and maximum values. I want the minimum width of the master view to be half the width of the device in portrait mode which will be the minimum of the view width and height regardless of the launch orientation.

CGFloat minimumWidth = MIN(CGRectGetWidth(splitViewController.view.bounds),CGRectGetHeight(splitViewController.view.bounds));
splitViewController.minimumPrimaryColumnWidth = minimumWidth / 2;
splitViewController.maximumPrimaryColumnWidth = minimumWidth;

The maximum value is less important as long as it does not constrain the minimum width. The appearance in portrait mode is unchanged but the landscape mode is now better proportioned:

As always you can find the full code example in my GitHub repository