Ios8 iOS 8 presentationController确定是否真的是popover
我正在使用iOS 8新的自适应“显示为Popover”功能。我在故事板上编了一个简单的片段来做演示。它在iphone6plus上工作得非常好,因为它将视图显示为popover,在iphone4s上显示为全屏视图(活页样式) 问题是当显示为全屏视图时,我需要在视图中添加一个“完成”按钮,以便调用dismissViewControllerAnimated。我不想在显示为popover时显示“完成”按钮Ios8 iOS 8 presentationController确定是否真的是popover,ios8,uipopovercontroller,adaptive-layout,Ios8,Uipopovercontroller,Adaptive Layout,我正在使用iOS 8新的自适应“显示为Popover”功能。我在故事板上编了一个简单的片段来做演示。它在iphone6plus上工作得非常好,因为它将视图显示为popover,在iphone4s上显示为全屏视图(活页样式) 问题是当显示为全屏视图时,我需要在视图中添加一个“完成”按钮,以便调用dismissViewControllerAnimated。我不想在显示为popover时显示“完成”按钮 NSLog( @"View loaded %lx", (long)self.presentatio
NSLog( @"View loaded %lx", (long)self.presentationController.adaptivePresentationStyle ); // UIModalPresentationFullScreen
NSLog( @"View loaded %lx", (long)self.presentationController.presentationStyle ); // UIModalPresentationPopover
NSLog( @"View loaded %lx", (long)self.popoverPresentationController.adaptivePresentationStyle ); // UIModalPresentationFullScreen
NSLog( @"View loaded %lx", (long)self.popoverPresentationController.presentationStyle ); // UIModalPresentationPopover
我试着查看presentationController和popoverPresentationController的属性,但我找不到任何东西可以告诉我它是否实际显示为popover
NSLog( @"View loaded %lx", (long)self.presentationController.adaptivePresentationStyle ); // UIModalPresentationFullScreen
NSLog( @"View loaded %lx", (long)self.presentationController.presentationStyle ); // UIModalPresentationPopover
NSLog( @"View loaded %lx", (long)self.popoverPresentationController.adaptivePresentationStyle ); // UIModalPresentationFullScreen
NSLog( @"View loaded %lx", (long)self.popoverPresentationController.presentationStyle ); // UIModalPresentationPopover
adaptivePresentationStyle始终返回UIModalPresentationFullScreen,presentationStyle始终返回UIModalPresentationPopover
在查看UITraitCollection时,我确实发现了一个名为“\u UITraitNameInteractionModel”的特性,当它实际显示为Popover时,该特性仅设置为1。然而,苹果并没有通过跟踪收集popoverPresentationController来提供对该特性的直接访问。管理视图控制器的
UIPresentationController
通过将modalPresentationStyle
设置为UIModalPresentationPopover
来呈现视图控制器
根据UIViewController
:
显示视图控制器
- 显示此视图的视图控制器 控制器。(只读)
- UIModalPresentationPopover:在水平规则环境中,内容显示在popover视图中的一种表示样式。背景内容变暗并点击 在popover之外,导致popover被解雇。如果你不 要关闭弹出窗口,可以将一个或多个视图指定给 关联对象的passthroughview属性 UIPopoverPresentationController对象,可以从 popoverPresentationController属性
horizontalSizeClass
来确定您的视图控制器是在popover中还是以模式显示(我假设您的按钮是UIBarButtonim
)
检查这一点最安全的地方是在
视图中将出现:
,否则显示的iewcontroller
可能是nil
我检查视图布局后是否设置了popoverPresentationController的箭头方向。就我的目的而言,这已经足够好了,并且涵盖了较小屏幕设备上的弹出框
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if (popoverPresentationController?.arrowDirection != UIPopoverArrowDirection.Unknown) {
// This view controller is running in a popover
NSLog("I'm running in a Popover")
}
}
怎么样
if (self.modalPresentationStyle == UIModalPresentationPopover)
这对我来说很有效我发现最好的方法(最不难闻)就是使用UIPopoverPresentationControllerDelegate
•确保显示的视图控制器设置为用于管理显示的uipoperpresentationcontroller
上的uipoperpresentationcontrollerdelegate
。我使用的是故事板,所以在prepareforsgue:
segue.destinationViewController.popoverPresentationController.delegate = presentedVC;
•在显示的视图控制器中创建属性以跟踪此状态:
@property (nonatomic, assign) BOOL amDisplayedInAPopover;
•并添加以下委托方法(或添加到现有委托方法):
•然后最后在视图中将出现:
-视图加载:
太早了,在视图加载:
和视图将出现:
if (self.amDisplayedInAPopover) {
// Hide the offending buttons in whatever manner you do so
self.navigationItem.leftBarButtonItem = nil;
}
编辑:更简单的方法强>
只需设置代理(确保演示的DVC采用UIPopoverPresentationControllerDelegate
):
并提供以下方法:
- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController
{
// This method is only called if we are presented in a popover
// Hide the offending buttons in whatever manner you do so
self.navigationItem.leftBarButtonItem = nil;
}
实现这一点的正式方法是首先从视图控制器中删除“完成”按钮,然后在适应compact时将视图控制器嵌入到导航控制器中,将“完成”按钮添加为导航项:
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.FullScreen
}
func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
let navigationController = UINavigationController(rootViewController: controller.presentedViewController)
let btnDone = UIBarButtonItem(title: "Done", style: .Done, target: self, action: "dismiss")
navigationController.topViewController.navigationItem.rightBarButtonItem = btnDone
return navigationController
}
func dismiss() {
self.dismissViewControllerAnimated(true, completion: nil)
}
我测试了本文中介绍的所有解决方案。抱歉,在所有情况下都不能正常工作。例如,在iPad中,当拖动拆分视图线时,拆分视图显示样式可能会发生变化,因此我们需要对此进行特定的通知。 经过几个小时的研究,我在苹果样品(swift)中找到了解决方案: 以下是obj-c中的相同解决方案 在prepareForSegue函数中,首先设置popoverPresentationController委托。它也可以在MyViewController“init”中设置,但不能在“viewDidLoad”中设置(因为在viewDidLoad之前调用first willPresentWithAdaptiveStyle) 现在,每当iOS更改演示样式(包括首次演示)时,MyViewController对象都会收到此通知。下面是显示/隐藏navigationController中“关闭”按钮的示例实现:
- (void)presentationController:(UIPresentationController *)presentationController
willPresentWithAdaptiveStyle:(UIModalPresentationStyle)style
transitionCoordinator:(nullable id<UIViewControllerTransitionCoordinator>)transitionCoordinator {
if (style == UIModalPresentationNone) {
// style set in storyboard not changed (popover), hide close button
self.topViewController.navigationItem.leftBarButtonItem = nil;
} else {
// style changed by iOS (to fullscreen or page sheet), show close button
UIBarButtonItem *closeButton =
[[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(closeAction)];
self.topViewController.navigationItem.leftBarButtonItem = closeButton;
}
}
- (void)closeAction {
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
-(void)presentationController:(UIPresentationController*)presentationController
将使用AdaptiveStyle:(UIModalPresentationStyle)样式呈现
transitionCoordinator:(可为null的id)transitionCoordinator{
if(style==UIModalPresentationNone){
//情节提要中的样式集未更改(popover),隐藏关闭按钮
self.topViewController.navigationItem.LeftBarButtonim=nil;
}否则{
//iOS更改的样式(全屏或页面),显示关闭按钮
UIBarButtonItem*关闭按钮=
[[UIBarButtonItem alloc]initWithTitle:@“关闭”样式:UIBarButtonItemStylePlain目标:自我操作:@selector(closeAction)];
self.topViewController.navigationItem.leftBarButtonItem=closeButton;
}
}
-(无效)封闭行动{
[self.presentingViewController dismissViewControllerAnimated:YES完成:nil];
}
多任务解决方案
将演示控制器指定为popover的委托
...
controller.popoverPresentationController.delegate = controller;
[self presentViewController:controller animated:YES completion:nil];
然后,在控制器中,实现委托方法:
- (void)presentationController:(UIPresentationController *)presentationController willPresentWithAdaptiveStyle:(UIModalPresentationStyle)style transitionCoordinator:(id<UIViewControllerTransitionCoordinator>)transitionCoordinator
{
if (style != UIModalPresentationNone)
{
// Exited popover mode
self.navigationItem.leftBarButtonItem = button;
}
}
- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController
{
// Entered popover mode
self.navigationItem.leftBarButtonItem = nil;
}
-(void)presentationController:(UIPresentationController*)presentationController将与AD一起显示
- (void)presentationController:(UIPresentationController *)presentationController
willPresentWithAdaptiveStyle:(UIModalPresentationStyle)style
transitionCoordinator:(nullable id<UIViewControllerTransitionCoordinator>)transitionCoordinator {
if (style == UIModalPresentationNone) {
// style set in storyboard not changed (popover), hide close button
self.topViewController.navigationItem.leftBarButtonItem = nil;
} else {
// style changed by iOS (to fullscreen or page sheet), show close button
UIBarButtonItem *closeButton =
[[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(closeAction)];
self.topViewController.navigationItem.leftBarButtonItem = closeButton;
}
}
- (void)closeAction {
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
...
controller.popoverPresentationController.delegate = controller;
[self presentViewController:controller animated:YES completion:nil];
- (void)presentationController:(UIPresentationController *)presentationController willPresentWithAdaptiveStyle:(UIModalPresentationStyle)style transitionCoordinator:(id<UIViewControllerTransitionCoordinator>)transitionCoordinator
{
if (style != UIModalPresentationNone)
{
// Exited popover mode
self.navigationItem.leftBarButtonItem = button;
}
}
- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController
{
// Entered popover mode
self.navigationItem.leftBarButtonItem = nil;
}
if (self.view.superview!.bounds != UIScreen.main.bounds) {
print("This is a popover!")
}