Change the width of Master in UISplitViewController
Solution 1
If you subclass UISplitViewController, you can implement -viewDidLayoutSubviews
and adjust the width there. This is clean, no hacks or private APIs, and works even with rotation.
- (void)viewDidLayoutSubviews
{
const CGFloat kMasterViewWidth = 240.0;
UIViewController *masterViewController = [self.viewControllers objectAtIndex:0];
UIViewController *detailViewController = [self.viewControllers objectAtIndex:1];
if (detailViewController.view.frame.origin.x > 0.0) {
// Adjust the width of the master view
CGRect masterViewFrame = masterViewController.view.frame;
CGFloat deltaX = masterViewFrame.size.width - kMasterViewWidth;
masterViewFrame.size.width -= deltaX;
masterViewController.view.frame = masterViewFrame;
// Adjust the width of the detail view
CGRect detailViewFrame = detailViewController.view.frame;
detailViewFrame.origin.x -= deltaX;
detailViewFrame.size.width += deltaX;
detailViewController.view.frame = detailViewFrame;
[masterViewController.view setNeedsLayout];
[detailViewController.view setNeedsLayout];
}
}
Solution 2
In IOS 8.0 you can easily do this by doing the following:
1. In your MasterSplitViewController.h add
@property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0);
2. In your MasterSplitViewController.m viewDidLoad method add
self.maximumPrimaryColumnWidth = 100;
self.splitViewController.maximumPrimaryColumnWidth = self.maximumPrimaryColumnWidth;
This is a really good, simple and easy feature of IOS 8.
Solution 3
this code is work for me
[splitViewController setValue:[NSNumber numberWithFloat:200.0] forKey:@"_masterColumnWidth"];
Solution 4
No.
There are two private properties
@property(access,nonatomic) CGFloat masterColumnWidth;
@property(access,nonatomic) CGFloat leftColumnWidth; // both are the same!
but being private mean they can't be used for AppStore apps.
Solution 5
iOS 8 introduced a new property:
// An animatable property that can be used to adjust the maximum absolute width of the primary view controller in the split view controller.
@property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0); // default: UISplitViewControllerAutomaticDimension
Use this property to adjust your master viewcontroller to your desired width.
Related videos on Youtube
Raj Pawan Gumdal
Updated on April 11, 2020Comments
-
Raj Pawan Gumdal about 4 years
The iPad programming guide says that the splitView's left pane is fixed to 320 points. But 320 pixels for my master view controller is too much. I would like to reduce it and give more space to detail view controller. Is it possible by anyway?
Link to the document which speaks about fixed width.
-
oliveryas01 over 13 yearsWhy not try Matt Gemmell's excellent MGSplitViewController? It's open source, and is available on GitHub. Gregor, Sweden
-
-
Raj Pawan Gumdal about 14 yearsThanks, but I am not going to use the private APIs, rather I would implement own split view controller . . .
-
nacho4d almost 14 yearsI know that privates can be modified using categories like this one, but this is the second time I try it and getting the same error:"_OBJC_IVAR_$_UISplitViewController._masterColumnWidth", referenced from: _OBJC_IVAR_$_UISplitViewController._masterColumnWidth$non_lazy_ptr in UISplitViewController+myExt.o (maybe you meant: _OBJC_IVAR_$_UISplitViewController._masterColumnWidth$non_lazy_ptr) Symbol(s) not found. Collect2: ld returned 1 exit status
-
Raj Pawan Gumdal over 13 yearsI am afraid that we will be changing the private properties in this case. Better not do it. Who knows, Apple might decide to change its class hierarchy?
-
Dan Rosenstark almost 13 years@Raj @pryiyanka, also you're assured rejection in the appstore.
-
Raj Pawan Gumdal almost 13 yearsYes, and thats the reason why I have implemented own SplitViewController, Matt Gamell's splitViewController didnt exist back then but now you can use MGSplitViewController, its good.
-
Kyle Clegg over 11 years@Raj how could I subclass UISplitViewController and only override the masterColumnWidth?
-
Raj Pawan Gumdal over 11 years@Kyle - Cannot go with the above approach, if you want to submit the app to appstore. Otherwise, if you still insist using it, you dont have to subclass it. See this answer below: stackoverflow.com/a/4022406/260665
-
Kyle Clegg over 11 years@Raj - I need to submit to the App Store. Is there a way to use the answer you suggested in a fashion that Apple will accept? I am assuming the answer is a subclass, or is that bad too?
-
Raj Pawan Gumdal over 11 yearsNo no, I am changing the accepted answer for posterity sake. You cannot use this approach or even subclass and change the width if you want to submit to appstore. It will be rejected for sure. Use Matt Gemmell's split view controller. See my new accepted answer.
-
Cutetare over 10 yearsWould this cause the app to be rejected at the AppStore?
-
jrc over 10 yearsI don't see why it would, as no private APIs are used.
-
Charlie Seligman over 10 yearsThis worked great for me in landscape but when I went back to portrait the view was shifted left. Any ideas how to resolve that?
-
jrc over 10 yearsGood catch. Edited my answer.
-
nigong over 10 yearsI can correctly resize the master view, however when the detailViewController.view.frame gets a new value, the app just goes purely black. Any idea?
-
kmiklas about 10 yearsIn iOS7, this worked for me: [self.splitViewController setValue:@78 forKey:@"_masterColumnWidth"];
-
d512 about 10 yearsThis should be the accepted answer. It's ridiculous that Apple makes you jump through hoops like this when they could easily expose a setting, but I'm glad you shared this.
-
lordB8r almost 10 years@nigong I'm getting the same problem. It somehow causes an infinite loop that I cannot get out of. If I don't set detailViewController.view.frame = detailViewFrame, then the masterViewController.view.frame updates correctly, but the detail doesn't. If I uncomment it, I get an infinite loop :(
-
DaSilva over 9 yearsdid you got any solution for the infinite loop? @AndréCytryn
-
Andre Cytryn over 9 yearsyes. on my subclass I added:
self.preferredPrimaryColumnWidthFraction = 0.3
but the thing is that I does not go more than 0.4 I dont know why -
Bill over 9 yearsThe black screen only happens on iOS 8. On iOS 8, you don't need this code - use
maximumPrimaryColumnWidth
instead. On iOS 7, the black screen doesn't occur and @jrc's solution works. -
Kenny Wyland over 9 yearsINFINITE LOOP AVOIDANCE: Some change in iOS8 is what causes the infinite loop. To avoid it, we used the above code, but wrapped it in an if() block that checked for the version of iOS. If it's less than 8.0, then use the above code, else, just set: self.maximumPrimaryColumnWidth = masterViewWidth; Please go upvote @SJTriggs and Twan's answers for this solution.
-
romiem over 9 yearsWould anyone be able to provide me the Swift equivalent of this code please? I can't seem to get this working in a Swift project.
-
romiem over 9 yearsNever mind, I managed to find the solution (although it is a bit different) stackoverflow.com/questions/2949067/…
-
Jason G over 9 yearsadd splitViewController.maximumPrimaryColumnWidth = ### to your appdelegate.swift
-
Erik van der Neut about 9 yearsInfinite loop is obviously very easy to avoid (test whether you already have the width you're after and only change it if you don't), but as Bill pointed out above: use
maximumPrimaryColumnWidth
on iOS8 and if you still support iOS7, then follow jrc's solution (although I would still improve that with a check of whether you need to adjust the width or not). -
aroon65 about 9 yearsThis approach mostly works (+1) but introduces a secondary problem. There is a transparent view used to detect touches outside the master area and instigate closure of the master. If this view's frame isn't updated to be the same as the detail view's frame, it becomes possible for the user to interact with the details whilst the master is open. To fix this, I did this:
this.View.Subviews[2].Frame = detailFrame;
straight after setting the detail frame. -
malhal over 8 yearsSince there are many different screen sizes you are better using preferredPrimaryColumnWidthFraction
-
JJack_ almost 8 yearsUsed with iOS 10 GM, xCode 8 and Swift 2.3. It works like a charm! :)
-
AppsolutEinfach almost 8 yearsWorked still under iOS 9, now under iOS 10 it crashes!
-
Himanshu jamnani over 7 yearsIt will crash for iOS10