在UISplitViewController中更改主设备的宽度

iPad编程指南指出,splitView的左窗格固定为320点。 但是我的主视图控制器的320像素太多了。 我想减less它,并给予更多的空间来详细视图控制器。 反正可能吗?

链接到说明固定宽度的文档 。

如果你是UISplitViewController的子类,你可以实现-viewDidLayoutSubviews并在那里调整宽度。 这是干净的,没有黑客或私人的API,即使旋转工作。

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

在IOS 8.0中,您可以通过执行以下操作轻松完成此操作:

1.在你的MasterSplitViewController.h中添加

 @property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0); 

2.在你的MasterSplitViewController.m中添加viewDidLoad方法

  self.maximumPrimaryColumnWidth = 100; self.splitViewController.maximumPrimaryColumnWidth = self.maximumPrimaryColumnWidth; 

这是IOS 8的一个非常好,简单和容易的特性。

这个代码适合我

 [splitViewController setValue:[NSNumber numberWithFloat:200.0] forKey:@"_masterColumnWidth"]; 

没有。


有两个私人财产

 @property(access,nonatomic) CGFloat masterColumnWidth; @property(access,nonatomic) CGFloat leftColumnWidth; // both are the same! 

但私人的意思是他们不能用于AppStore应用程序。

为什么不试试Matt Gemmell出色的MGSplitViewController ? 它是开源的,可以在GitHub上find 。

瑞典格雷戈尔

iOS 8引入了一个新的属性:

 // 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 

使用这个属性来调整你的主视图控制器到你想要的宽度。

下面是我如何在iOS8中用Swift做到的。

 class MainSplitViewController: UISplitViewController { override func viewDidLoad() { self.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible self.maximumPrimaryColumnWidth = 100 // specify your width here } } 

如果您需要在分割视图中的主/细节视图内dynamic更改宽度,请执行如下操作:

 var splitViewController = self.splitViewController as MainSplitViewController splitViewController.maximumPrimaryColumnWidth = 400 

没有任何答案在iOS7上为我工作,所以我做了一些我自己的研究,并创build了一个工作的解决scheme。 这将涉及UISplitViewController的全部function的子类。

我将给出答案,就好像我们刚刚为所有设备方向创build了一个iPad项目,并将自定义的UISplitViewController设置为主视图控制器。

创build你自定义的UISplitViewController 。 在这个例子中,mine被称为MySplitViewController 。 所有代码将基于MySplitViewController.m

我们将需要从UISplitViewControllerDelegate访问一个方法,添加并设置委托。 我们还将设置代理转发器,因此您需要调用另一个类的代理方法。

 @interface MySplitViewController () <UISplitViewControllerDelegate> @property (nonatomic, weak) id<UISplitViewControllerDelegate> realDelegate; @end @implementation MySplitViewController - (instancetype)init { self = [super init]; if (self) { self.delegate = self; } return self; } - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { self.delegate = self; } return self; } - (void)setDelegate:(id<UISplitViewControllerDelegate>)delegate { [super setDelegate:nil]; self.realDelegate = (delegate != self) ? delegate : nil; [super setDelegate:delegate ? self : nil]; } - (BOOL)respondsToSelector:(SEL)aSelector { id delegate = self.realDelegate; return [super respondsToSelector:aSelector] || [delegate respondsToSelector:aSelector]; } - (id)forwardingTargetForSelector:(SEL)aSelector { id delegate = self.realDelegate; return [delegate respondsToSelector:aSelector] ? delegate : [super forwardingTargetForSelector:aSelector]; } 

设置主视图和详细视图控制器。

 - (void)viewDidLoad { [super viewDidLoad]; UIViewController* masterViewController = [[UIViewController alloc] init]; masterViewController.view.backgroundColor = [UIColor yellowColor]; UIViewController* detailViewController = [[UIViewController alloc] init]; detailViewController.view.backgroundColor = [UIColor cyanColor]; self.viewControllers = @[masterViewController, detailViewController]; } 

让我们添加我们所需的宽度的方法,以方便参考。

 - (CGFloat)desiredWidth { return 200.0f; } 

在呈现之前,我们将操纵主视图控制器。

 - (void)splitViewController:(UISplitViewController *)svc popoverController:(UIPopoverController *)pc willPresentViewController:(UIViewController *)aViewController { id realDelegate = self.realDelegate; if ([realDelegate respondsToSelector:@selector(splitViewController:popoverController:willPresentViewController:)]) { [realDelegate splitViewController:svc popoverController:pc willPresentViewController:aViewController]; } CGRect rect = aViewController.view.frame; rect.size.width = [self desiredWidth]; aViewController.view.frame = rect; aViewController.view.superview.clipsToBounds = NO; } 

但是,现在我们剩下这样的显示了。 在这里输入图像描述

所以要重写一个私有方法。 是的私人方法,它仍然是可以接受的,因为它不是一个下划线的私人方法。

 - (CGFloat)leftColumnWidth { return [self desiredWidth]; } 

这涉及肖像模式。 所以类似的事情为-splitViewController:willShowViewController:invalidatingBarButtonItem:你应该设置景观。

但是在iOS8中不需要这些。 您将可以简单地调用最小和最大宽度属性!

故事板的方式将是@Tim提到的这一个:

在这里输入图像描述

此外,如果您希望主视图总是占用一定比例的屏幕,则可以使用Key Path =“preferredPrimaryColumnWidthFraction”,并将值设置为0.2(对于20%的屏幕大小)。

请注意,“maximumPrimaryColumnWidth”设置为320,所以如果你尝试0.5的屏幕百分比值(50%),它将不会超过320.如果你需要覆盖这个值,你可以为maximumPrimaryColumnWidth添加一个键path。

在分配给rootviewcontroller之前使用下面的代码。 它适用于我与ios7

[self.splitViewController setValue:[NSNumber numberWithFloat:256.0] forKey:@"_masterColumnWidth"]; self.window.rootViewController = self.splitViewController;

由于没有人提到这可以从IB完成,我想添加这个答案。 显然,您可以为UISplitViewContorller设置“用户定义的运行属性”,具体如下:键path:masterColumnWidthtypes:数字值:250

您可以使用GSSplitViewController 。 这一个将在iOS 7和8上工作

 splitView = [[GSSplitViewController alloc] init]; splitView.masterPaneWidth = 180; 

您也可以通过将pod 'GSSplitViewController'添加到您的Podfile来包含它。

ViewController.h @property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0);

ViewController.m

 #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) if (SYSTEM_VERSION_LESS_THAN(@"10.0")) { [self setValue:[NSNumber numberWithFloat:200.0]forKey:@"_masterColumnWidth"]; }else{ self.maximumPrimaryColumnWidth = 200; self.splitViewController.maximumPrimaryColumnWidth = self.maximumPrimaryColumnWidth; } 

Swift 3.0你使用像

 let widthfraction = 2.0 //Your desired value for me 2.0 splitViewController?.preferredPrimaryColumnWidthFraction = 0.40 let minimumWidth = min((splitViewController?.view.bounds.size.width)!,(splitViewController?.view.bounds.height)!) splitViewController?.minimumPrimaryColumnWidth = minimumWidth / widthFraction splitViewController?.maximumPrimaryColumnWidth = minimumWidth / widthFraction let leftNavController = splitViewController?.viewControllers.first as! UINavigationController leftNavController.view.frame = CGRect(x: leftNavController.view.frame.origin.x, y: leftNavController.view.frame.origin.y, width: (minimumWidth / widthFraction), height: leftNavController.view.frame.height) 

就我而言,我必须设置最大值和最小值来完成这项工作

 mySplitViewController.preferredDisplayMode = .allVisible; mySplitViewController.maximumPrimaryColumnWidth = UIScreen.main.bounds.width/2; mySplitViewController.minimumPrimaryColumnWidth = UIScreen.main.bounds.width/2; 

这个代码适合我:)

 @interface UISplitViewController(myExt) 
 - (void)setNewMasterSize:(float)size; 
 @结束 

@implementation UISplitViewController(myExt)
– (void)setNewMasterSize:(float)size
{
_masterColumnWidth = size;
}
@结束

并使用它在每个操作与视图(如旋转)