在UISplitViewController中更改Master的宽度

Raj*_*dal 41 ipad uisplitviewcontroller ios

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

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

jrc*_*jrc 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];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 无限循环避免:iOS8中的一些变化是导致无限循环的原因.为避免这种情况,我们使用了上面的代码,但将其包装在检查iOS版本的if()块中.如果它小于8.0,则使用上面的代码,否则,只需设置:self.maximumPrimaryColumnWidth = masterViewWidth; 请为这个解决方案提供@SJTriggs和Twan的答案. (5认同)
  • 我不明白为什么会这样,因为没有使用私有API. (3认同)
  • 这应该是公认的答案.当苹果公司轻松揭开环境时,让你跳过这样的篮球是很荒谬的,但我很高兴你能分享这个. (3认同)
  • 黑屏仅在iOS 8上发生.在iOS 8上,您不需要此代码 - 请改用"maximumPrimaryColumnWidth".在iOS 7上,黑屏不会出现,@ jrc的解决方案也可以. (3认同)

SJT*_*ggs 35

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

1.在您的MasterSplitViewController.h中添加

@property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0);
Run Code Online (Sandbox Code Playgroud)

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

 self.maximumPrimaryColumnWidth = 100;
 self.splitViewController.maximumPrimaryColumnWidth = self.maximumPrimaryColumnWidth;
Run Code Online (Sandbox Code Playgroud)

这是IOS 8非常好,简单易用的功能.

  • 与iOS 10 GM,xCode 8和Swift 2.3一起使用.它就像一个魅力!:) (2认同)

pri*_*nka 22

这段代码对我有用

[splitViewController setValue:[NSNumber numberWithFloat:200.0] forKey:@"_masterColumnWidth"];
Run Code Online (Sandbox Code Playgroud)

  • @Raj @pryiyanka,你也确信在appstore中被拒绝了. (2认同)
  • iOS10会崩溃 (2认同)

ken*_*ytm 12

没有.


有两个私人财产

@property(access,nonatomic) CGFloat masterColumnWidth;
@property(access,nonatomic) CGFloat leftColumnWidth; // both are the same!
Run Code Online (Sandbox Code Playgroud)

但私有意味着他们不能用于AppStore应用程序.

  • 谢谢,但我不会使用私有API,而是我会实现自己的拆分视图控制器... (2认同)

Ant*_*ine 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
Run Code Online (Sandbox Code Playgroud)

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

  • 由于有许多不同的屏幕尺寸,因此最好使用preferredPrimaryColumnWidthFraction (2认同)

rom*_*iem 7

以下是我在iOS8中使用Swift的方法.

class MainSplitViewController: UISplitViewController {

    override func viewDidLoad() {

        self.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
        self.maximumPrimaryColumnWidth = 100 // specify your width here
    }
}
Run Code Online (Sandbox Code Playgroud)

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

var splitViewController = self.splitViewController as MainSplitViewController
splitViewController.maximumPrimaryColumnWidth = 400
Run Code Online (Sandbox Code Playgroud)


cno*_*gr8 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];
}
Run Code Online (Sandbox Code Playgroud)

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

- (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];
}
Run Code Online (Sandbox Code Playgroud)

让我们将所需的宽度添加到方法中以便于参考.

- (CGFloat)desiredWidth {
    return 200.0f;
}
Run Code Online (Sandbox Code Playgroud)

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

- (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;
}
Run Code Online (Sandbox Code Playgroud)

但是,现在我们留下了这样的显示器. 在此输入图像描述

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

- (CGFloat)leftColumnWidth {
    return [self desiredWidth];
}
Run Code Online (Sandbox Code Playgroud)

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

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


Tra*_* M. 5

故事板的方式就是这个,由@Tim提到:

在此输入图像描述

此外,如果您希望主视图始终占据屏幕的某个百分比,则可以使用Key Path ="preferredPrimaryColumnWidthFraction",并将值设置为0.2(屏幕大小为20%).

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