UISplitViewController:如何强制在应用启动时显示主弹出框? (肖像)
Posted
技术标签:
【中文标题】UISplitViewController:如何强制在应用启动时显示主弹出框? (肖像)【英文标题】:UISplitViewController: How force to show master popover in app launch? (portrait) 【发布时间】:2012-05-03 07:02:51 【问题描述】:在 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 的一些建议?
【问题讨论】:
这是一个很好的答案:***.com/a/15817100/733862 【参考方案1】:这里没有 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。
【讨论】:
这会强制并排显示。它不会按照 OP 的要求在弹出模式下显示主视图。 @phatmann,我认为 alejandromp 不是在谈论 popover。他说我需要强制显示主弹出框,但实际上这并不意味着什么。考虑到上下文,他确实谈到了在纵向模式下并排显示主视图,就像在横向模式中一样。 也可以调用detailViewController【参考方案2】:我在这个问题上苦苦挣扎了一段时间,即使现在我对这个解决方案也不是 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];
在这种情况下,您可以在拆分视图委托方法中直接执行选择器。
【讨论】:
谢谢。我用你的代码加上我以前的代码来做这个。但有时应用程序崩溃。我认为这是因为我在 splitViewController 委托中执行此操作,并且在某些情况下,它可能是未完全创建的控制器。现在我用 perfromSelectorAfterDelay 编写代码并且工作得很好。谢谢。 这将导致编译器可能出现内存泄漏警告【参考方案3】:扩展 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
【讨论】:
这太棒了,而且效果很好!但是它给了我一个警告,“PerformSelector 可能会导致泄漏,因为它的选择器是未知的”你知道为什么以及如何处理它吗? AFAIK 编译器分析方法调用并添加代码来管理 ARC 引用计数器(以管理垃圾收集)。调用这样的方法有点像在 Java 中使用反射(在运行时完成),因此在这种情况下编译器无法发挥其 refCount 魔法。但是,只要调用的方法不返回任何分配的对象(这将是一个泄漏),它就不会有任何问题。在这种情况下,我们不会从被调用的方法返回任何内容。为避免此警告,请参阅:learningipadprogramming.com/2012/04/03/… 如果细节视图控制器中没有加载任何内容,这将不起作用,这将是强制主显示的要点。 @VictorEngel 确实如此,但由于此代码进入详细视图,因此您需要确保默认加载一个空的详细视图。【参考方案4】:对于 iOS8,最简单的方法是:
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
我在第一次启动应用程序时使用它来显示 masterViewController 中的登录。 在所有其他情况下,我使用
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic
【讨论】:
【参考方案5】:如果您在应用启动时需要它,请在您的详细视图控制器中覆盖此方法:
-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
return NO;
但是,如果您随后需要它隐藏它,它看起来好像没有调用该方法,所以您必须手动隐藏它。
【讨论】:
这在 iOS 8 中已被弃用。【参考方案6】:稍微不那么老套的变体(swift):
let btn = self.splitViewController!.displayModeButtonItem()
btn.target?.performSelector(btn.action, withObject: btn)
【讨论】:
【参考方案7】:我使用这个解决方案: 在 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 启动时显示,并且在方向改变后具有默认行为。
【讨论】:
【参考方案8】:无需保留对 barButtonItem 的愚蠢引用。只需调用相同的目标/动作。看我的回答https://***.com/a/25695923/1021430
target是split view controller,action是toggleMasterVisible:
【讨论】:
toggleMasterVisible 是一个私有方法。以上是关于UISplitViewController:如何强制在应用启动时显示主弹出框? (肖像)的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 uisplitviewcontroller 在纵向模式下并排设置主视图/详细视图
如何在横向全屏 UISplitViewController 的 DetailView
关闭uisplitviewcontroller中的NavigationController后如何重新加载tableView?
如何在 UISplitViewController 的导航栏下方添加搜索栏?