27

在 iPad 应用程序中,我正在使用 UISplitViewController。当应用程序以纵向模式启动时,我需要强制显示主弹出窗口。

现在我正在使用这段代码,它在 iOS 5.0 上运行良好。

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
   if ([[[AppDelegate sharedAppDelegate] splitViewController] respondsToSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]]) {
      [[[AppDelegate sharedAppDelegate] splitViewController] performSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]];
   }            
}

但在 iOS 5.1(使用新型主弹出框)中,行为似乎是随机的。有时弹出窗口会全屏显示,有时效果很好。

5.1的一些建议?

4

8 回答 8

27

这里没有 5.1 的建议,但 8.0 的建议:

现在有了iOS8,有很多新的UISplitViewController配置方法。

在您的情况下,只需在 中设置正确的值preferredDisplayMode,例如在 masterViewController 中viewDidLoad

目标-C:

- (void)viewDidLoad {
    // configuring splitviewcontroller
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;

    //....
}

迅速:

    override func viewDidLoad() {
        self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
    }

但这当然只是iOS8。

于 2014-10-09T09:26:14.973 回答
13

我为此苦苦挣扎了一段时间,即使现在我对解决方案也不是 100% 满意,但鉴于当前的限制,这是我唯一能想到的。

首先,重写以下委托方法:

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController

并使用它来获取对条形按钮项的引用,并将其存储在 iVar 中:

barButtonForMaster = barButtonItem;

然后,当您想显示主视图控制器时,请进行如下调用:

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster];

如果您想在一开始就执行此操作,请使用一些延迟以防止应用程序崩溃(感谢有用的评论):

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster afterDelay:1];

在这种情况下,您可以在拆分视图委托方法中执行选择器。

于 2012-05-03T17:26:16.390 回答
13

扩展 Rob 的答案,这对我很有效(在详细屏幕的 viewDidLoad 中):

//If in portrait mode, display the master view
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    [self.navigationItem.leftBarButtonItem.target performSelector:self.navigationItem.leftBarButtonItem.action withObject:self.navigationItem];
}

无需获取单独的引用,而是使用 self.navigationItem.leftBarButtonItem

于 2012-11-06T19:01:24.700 回答
7

对于 iOS8,最简单的方法是使用以下方法:

 self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;

我在第一次启动应用程序时使用它来显示 masterViewController 中的登录。在所有其他情况下,我使用

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic
于 2015-05-29T09:35:08.927 回答
5

如果您在应用程序启动时需要它,请在您的详细视图控制器中覆盖此方法:

-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
    return NO;
}

但是,如果您随后需要它来隐藏它,它看起来好像没有调用该方法,因此您必须手动隐藏它。

于 2014-07-14T05:51:36.210 回答
1

一个稍微不那么骇人听闻的变体(swift):

let btn = self.splitViewController!.displayModeButtonItem()
btn.target?.performSelector(btn.action, withObject: btn)
于 2016-02-27T17:37:18.870 回答
1

我使用这个解决方案:
在 viewDidLoad 中的 splitViewController 中将 displayMode 设置为 .primaryOverlay

override func viewDidLoad() {
    if self.isCollapsed == false, self.displayMode == .primaryHidden {
        self.preferredDisplayMode = .primaryOverlay
    }
}

并在 viewWillAppear 中将其设置回 .automatic

override func viewWillAppear(_ animated: Bool) {
    self.preferredDisplayMode = .automatic
}

这样主视图将在 UISplitViewController 启动时显示,并且在方向改变后具有默认行为。

于 2017-07-15T22:30:20.597 回答
0

无需保留对 barButtonItem 的愚蠢引用。只需调用相同的目标/动作。查看我的答案https://stackoverflow.com/a/25695923/1021430

目标是拆分视图控制器,动作是toggleMasterVisible:

于 2014-09-06T01:23:15.933 回答