iOS 8 presentationController确定是否真的是popover

Tod*_*ham 16 uipopovercontroller ios8 adaptive-layout

我正在使用iOS 8的新自适应"Present As Popover"功能.我在StoryBoard中连接了一个简单的segue来进行演示.它适用于iPhone 6 Plus,因为它将视图显示为弹出窗口,而在iPhone 4s上则显示为全屏视图(工作表样式).

问题是当显示为全屏视图时,我需要在视图中添加"完成"按钮,以便可以调用dismissViewControllerAnimated.当它显示为弹出窗口时,我不想显示"完成"按钮.

在此输入图像描述

我试着查看presentationController和popoverPresentationController的属性,我什么也没发现,它告诉我它是否实际显示为弹出框.

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

adaptivePresentationStyle始终返回UIModalPresentationFullScreen,而presentationStyle始终返回UIModalPresentationPopover

在查看UITraitCollection时,我确实发现了一个名为"_UITraitNameInteractionModel"的特征,当它实际显示为Popover时,它只被设置为1.但是,Apple不通过popoverPresentationController的traitCollection直接访问该特征.

Rob*_*sey 13

我发现这样做的最好方法(最不臭)是使用UIPopoverPresentationControllerDelegate.

•确保所呈现的视图控制器被设置为UIPopoverPresentationControllerDelegateUIPopoverPresentationController被用来管理演示.我正在使用故事板,所以设置它prepareForSegue:

segue.destinationViewController.popoverPresentationController.delegate = presentedVC;
Run Code Online (Sandbox Code Playgroud)

•在显示的视图控制器中创建属性以跟踪此状态:

@property (nonatomic, assign) BOOL amDisplayedInAPopover;
Run Code Online (Sandbox Code Playgroud)

•并添加以下委托方法(或添加到现有的委托方法):

- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController
{
    // This method is only called if we are presented in a popover
    self.amDisplayedInAPopover = YES;
}
Run Code Online (Sandbox Code Playgroud)

•然后最后viewWillAppear:- viewDidLoad:太早了,委托制备方法在viewDidLoad:和之间调用viewWillAppear:

if (self.amDisplayedInAPopover) {
    // Hide the offending buttons in whatever manner you do so
    self.navigationItem.leftBarButtonItem = nil;
}
Run Code Online (Sandbox Code Playgroud)

编辑:更简单的方法!

只需设置代理(确保您的presentVC采用UIPopoverPresentationControllerDelegate):

segue.destinationViewController.popoverPresentationController.delegate = presentedVC;
Run Code Online (Sandbox Code Playgroud)

并提供方法:

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


小智 10

我检查了视图布局后是否设置了popoverPresentationController的arrowDirection.就我的目的而言,这种方法运行良好,涵盖了较小屏幕设备上的弹出窗口.

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