ios 在 UISplitViewController 中更改 Master 的宽度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2949067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change the width of Master in UISplitViewController
提问by Raj Pawan Gumdal
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?
iPad编程指南说splitView的左窗格固定为320点。但是我的主视图控制器 320 像素太多了。我想减少它并为细节视图控制器提供更多空间。反正有可能吗?
Link to the documentwhich speaks about fixed width.
链接到关于固定宽度的文档。
回答by jrc
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.
如果你继承 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];
}
}
回答by SJTriggs
In IOS 8.0 you can easily do this by doing the following:
在 IOS 8.0 中,您可以通过执行以下操作轻松完成此操作:
1. In your MasterSplitViewController.h add
1. 在你的 MasterSplitViewController.h 添加
@property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0);
2. In your MasterSplitViewController.m viewDidLoad method add
2. 在你的 MasterSplitViewController.m viewDidLoad 方法中添加
self.maximumPrimaryColumnWidth = 100;
self.splitViewController.maximumPrimaryColumnWidth = self.maximumPrimaryColumnWidth;
This is a really good, simple and easy feature of IOS 8.
这是 IOS 8 的一个非常好的、简单和容易的功能。
回答by priyanka
this code is work for me
这段代码对我有用
[splitViewController setValue:[NSNumber numberWithFloat:200.0] forKey:@"_masterColumnWidth"];
回答by kennytm
No.
不。
There are two privateproperties
有两个私有属性
@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.
但私有意味着它们不能用于 AppStore 应用程序。
回答by Antoine
iOS 8 introduced a new property:
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
Use this property to adjust your master viewcontroller to your desired width.
使用此属性将主视图控制器调整为所需的宽度。
回答by romiem
Here is how I did this in iOS8 with Swift.
以下是我在 iOS8 中使用 Swift 的方法。
class MainSplitViewController: UISplitViewController {
override func viewDidLoad() {
self.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
self.maximumPrimaryColumnWidth = 100 // specify your width here
}
}
If you need to change the width dynamically from within your master/detail view in the split view, then do something like this:
如果您需要在拆分视图中的主/详细视图中动态更改宽度,请执行以下操作:
var splitViewController = self.splitViewController as MainSplitViewController
splitViewController.maximumPrimaryColumnWidth = 400
回答by Travis M.
The storyboard way would be this one, mentioned by @Tim:
故事板的方式就是@Tim 提到的这种方式:
Furthermore, if you want the Master view to always take up a certain percentage of the screen then you can use the Key Path = "preferredPrimaryColumnWidthFraction" instead and set the value to 0.2 (for 20% screen size).
此外,如果您希望主视图始终占据屏幕的特定百分比,那么您可以使用 Key Path = "preferredPrimaryColumnWidthFraction" 并将值设置为 0.2(对于 20% 的屏幕大小)。
Please note that the "maximumPrimaryColumnWidth" is set to 320, so if you try the screen percent value of 0.5 (50%) it won't go above 320. You can add a key path for maximumPrimaryColumnWidth if you need to override this.
请注意,“maximumPrimaryColumnWidth”设置为 320,因此如果您尝试将屏幕百分比值设为 0.5 (50%),它不会超过 320。如果您需要覆盖它,您可以为 maximumPrimaryColumnWidth 添加一个关键路径。
回答by cnotethegr8
None of the answers worked for me on iOS7, so I did some of my own research and created a working solution. This will involve subclassing UISplitViewController
for the full functionality.
在 iOS7 上没有一个答案对我有用,所以我做了一些自己的研究并创建了一个可行的解决方案。这将涉及UISplitViewController
完整功能的子类化。
I will present the answer as if we just created a new project for iPad with all device orientations and have set the custom UISplitViewController
as the main view controller.
我将给出答案,就好像我们刚刚为 iPad 创建了一个具有所有设备方向的新项目,并将自定义设置UISplitViewController
为主视图控制器。
Create your custom UISplitViewController
. In this example mine is called MySplitViewController
. All code will be based in MySplitViewController.m
.
创建您的自定义UISplitViewController
. 在这个例子中, mine 被称为MySplitViewController
. 所有代码都将基于MySplitViewController.m
.
We're going to need to access a method from the UISplitViewControllerDelegate
so add that and set the delegate. We'll also setup a delegate forwarder incase you need to call the delegate methods from another class.
我们将需要访问一个方法,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];
}
Setup the master and detail view controllers.
设置主视图和细节视图控制器。
- (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];
}
Lets add our desired width to a method for easy reference.
让我们将我们想要的宽度添加到一个方法中以便于参考。
- (CGFloat)desiredWidth {
return 200.0f;
}
We'll manipulate the master view controller before presenting it.
在呈现它之前,我们将操纵主视图控制器。
- (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;
}
However, now we're left with a display like this.
但是,现在我们只剩下这样的显示了。
So were going to override a private method. Yes a private method, it will still be acceptable in the App Store since its not an underscore private method.
所以打算覆盖一个私有方法。是的私有方法,它在 App Store 中仍然可以接受,因为它不是下划线私有方法。
- (CGFloat)leftColumnWidth {
return [self desiredWidth];
}
This deals with portrait mode. So a similar thing for -splitViewController:willShowViewController:invalidatingBarButtonItem:
and you should be set for landscape.
这涉及纵向模式。所以类似的事情-splitViewController:willShowViewController:invalidatingBarButtonItem:
,你应该设置为横向。
However none of this will be needed in iOS8. You'll be able to simply call a min and max width property!
然而,在 iOS8 中这些都不需要。您将能够简单地调用最小和最大宽度属性!
回答by xevser
use the following code before assigning to the rootviewcontroller. It works for me with ios7
在分配给 rootviewcontroller 之前使用以下代码。它适用于我的 ios7
[self.splitViewController setValue:[NSNumber numberWithFloat:256.0] forKey:@"_masterColumnWidth"];
self.window.rootViewController = self.splitViewController;
[self.splitViewController setValue:[NSNumber numberWithFloat:256.0] forKey:@"_masterColumnWidth"];
self.window.rootViewController = self.splitViewController;
回答by Tim
Since no one mentioned that this can be done from IB, I want to add this answer. Apparently, you can set "User Defined Runtime Attributes" for the UISplitViewContorller with following details: Key Path:masterColumnWidth Type: Number Value: 250
由于没有人提到这可以从 IB 完成,我想添加这个答案。显然,您可以使用以下详细信息为 UISplitViewContorller 设置“用户定义的运行时属性”:Key Path:masterColumnWidth Type: Number Value: 250