46

iPad 编程指南说 splitView 的左窗格固定为 320 点。但是我的主视图控制器的 320 像素太多了。我想减少它并为细节视图控制器提供更多空间。反正有可能吗?

链接到有关固定宽度的文档。

4

16 回答 16

65

如果你继承 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];
    }
}
于 2013-10-03T11:48:06.343 回答
36

在 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 的一个非常好的、简单易用的功能。

于 2014-09-26T10:49:22.577 回答
22

这段代码对我有用

[splitViewController setValue:[NSNumber numberWithFloat:200.0] forKey:@"_masterColumnWidth"];
于 2010-10-26T09:39:53.723 回答
12

不。


有两个私有属性

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

但私有意味着它们不能用于 AppStore 应用程序。

于 2010-06-01T10:55:27.527 回答
10

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

使用此属性将主视图控制器调整为所需的宽度。

于 2014-09-21T10:40:47.663 回答
8

这是我在 iOS8 中使用 Swift 的方法。

class MainSplitViewController: UISplitViewController {

    override func viewDidLoad() {

        self.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
        self.maximumPrimaryColumnWidth = 100 // specify your width here
    }
}

如果您需要从拆分视图的主/详细视图中动态更改宽度,请执行以下操作:

var splitViewController = self.splitViewController as MainSplitViewController
splitViewController.maximumPrimaryColumnWidth = 400
于 2014-11-28T15:11:04.740 回答
6

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

在此处输入图像描述

此外,如果您希望主视图始终占据屏幕的某个百分比,那么您可以使用 Key Path = "preferredPrimaryColumnWidthFraction" 并将值设置为 0.2(对于 20% 的屏幕尺寸)。

请注意,“maximumPrimaryColumnWidth”设置为 320,因此如果您尝试将屏幕百分比值设为 0.5 (50%),它不会超过 320。如果您需要覆盖它,可以为 maximumPrimaryColumnWidth 添加一个关键路径。

于 2016-11-29T17:21:23.320 回答
5

在 iOS7 上,没有一个答案对我有用,所以我做了一些自己的研究并创建了一个可行的解决方案。这将涉及UISplitViewController完整功能的子类化。

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

创建您的自定义UISplitViewController. 在这个例子中,我的被称为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;
}

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

所以要覆盖一个私有方法。是的,私有方法,它在 App Store 中仍然可以接受,因为它不是下划线私有方法。

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

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

然而,在 iOS8 中这些都不需要。您将能够简单地调用最小和最大宽度属性!

于 2014-08-28T08:46:46.583 回答
2

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

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

于 2014-11-25T15:03:06.070 回答
2

由于没有人提到这可以从 IB 完成,我想添加这个答案。显然,您可以使用以下详细信息为 UISplitViewContorller 设置“用户定义的运行时属性”:键路径:masterColumnWidth 类型:数字值:250

于 2015-07-18T16:01:27.220 回答
2

就我而言,我必须同时设置最大值和最小值才能使这项工作

mySplitViewController.preferredDisplayMode = .allVisible;
mySplitViewController.maximumPrimaryColumnWidth = UIScreen.main.bounds.width/2;
mySplitViewController.minimumPrimaryColumnWidth = UIScreen.main.bounds.width/2; 
于 2017-06-12T18:13:03.633 回答
0

您可以使用GSSplitViewController。这个适用于 iOS 7 和 8

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

您也可以通过添加pod 'GSSplitViewController'到您的Podfile.

于 2015-06-17T12:31:34.593 回答
0

视图控制器.h @property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0);

视图控制器.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;

     }
于 2016-10-12T05:54:56.380 回答
0

你使用的 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)
于 2017-03-15T07:00:32.267 回答
0
// in UISplitViewController subclass
// let more space for detail in portrait mode
- (void)viewWillLayoutSubviews
{
    CGFloat width;
    if (UIInterfaceOrientationIsPortrait(UIApplication.sharedApplication.statusBarOrientation)){
        width = CGRectGetWidth(self.view.bounds) * 0.25f;
    }
    else {
        width = CGRectGetWidth(self.view.bounds) * 0.33f;
    }
    width = (NSInteger)fminf(260, fmaxf(120, width));
    self.minimumPrimaryColumnWidth = width;
    self.maximumPrimaryColumnWidth = width;

    [super viewWillLayoutSubviews];
}
于 2019-04-10T15:33:24.160 回答
-3

这段代码对我有用:)

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

@implementation UISplitViewController(myExt) - (void)setNewMasterSize:(float)size { _masterColumnWidth = size; } @end

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

于 2010-08-24T19:29:29.203 回答