如何修复"UIPopoverController已弃用"警告?

Var*_*ria 49 objective-c deprecated uipopovercontroller ios

我正在使用此代码:

mediaLibraryPopover = [[UIPopoverController alloc] 
                        initWithContentViewController:avc];
[self.mediaLibraryPopover presentPopoverFromRect:[theButton bounds] 
                          inView:theButton 
                          permittedArrowDirections:UIPopoverArrowDirectionAny 
                          animated:YES];
Run Code Online (Sandbox Code Playgroud)

我在Xcode 7中收到此警告:

不推荐使用UIPopoverController,在iOS 9.0中首先弃用 - 不推荐使用UIPopoverController.弹出窗口现在实现为UIViewController演示.使用UIModalPresentationPopover和UIPopoverPresentationController的模态表示样式.

Mid*_* MP 115

您不再需要UIPopoverController呈现视图控制器.相反,您可以将modalPresentationStyle视图控制器设置为UIModalPresentationPopover.

您可以使用以下代码:

avc.modalPresentationStyle = UIModalPresentationPopover;
avc.popoverPresentationController.sourceView = theButton;
[self presentViewController:avc animated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

UIModalPresentationPopover

在水平常规环境中,呈现样式,其中内容以弹出视图显示.背景内容变暗,弹出窗口外的水龙头导致弹出窗口被解除.如果您不想使用tap来关闭popover,可以将一个或多个视图分配给关联的UIPopoverPresentationController对象的passthroughViews属性,您可以从popoverPresentationController属性获取该属性.

在水平紧凑的环境中,此选项与UIModalPresentationFullScreen的行为相同.

适用于iOS 8.0及更高版本.

参考UIModalPresentationStyle参考


您需要设置其中一个sourceViewbarButtonItem属性,否则它将崩溃并显示以下消息:

***由于未捕获的异常'NSGenericException'而终止应用程序,原因是:'UIPopoverPresentationController(***)应该在演示发生之前设置一个非零的sourceView或barButtonItem.

要正确锚定弹出箭头,还需要指定sourceRect属性.

avc.modalPresentationStyle                   = UIModalPresentationPopover;
avc.popoverPresentationController.sourceView = self.view;
avc.popoverPresentationController.sourceRect = theButton.frame;
[self presentViewController:avc animated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅sourceViewsourceRect.

  • 我发现我需要更改`avc.popoverPresentationController.sourceView = self.view;`并添加`avc.popoverPresentationController.sourceRect = theButton.frame;`以便正确定位popover. (4认同)
  • @Anz:你需要设置popoverpresentationcontroller的`allowedArrowDirections`属性 (4认同)

qix*_*qix 7

Apple有官方的方式在这里展示和配置iOS8的popovers:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationController_class/index.html

虽然类似于@ MidhunMP的答案,但值得注意的是段落:

调用后配置弹出窗口控制器控制器presentViewController:animated:completion:可能看起来有点 违反直觉,但UIKit在您启动演示文稿之前不会创建演示文稿控制器.此外,UIKit必须等到下一个更新周期才能在屏幕上显示新内容.这种延迟使您有时间为弹出框配置演示控制器.

如果您愿意,也可以通过代理来配置和响应事件(https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationControllerDelegate_protocol/index.html).

举个例子,不要使用委托:

// Present the controller using the popover style.
controller.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:controller animated:YES completion:nil];

// Popover presentation controller was created when presenting; now  configure it.
UIPopoverPresentationController *presentationController =
        [controller popoverPresentationController];
presentationController.permittedArrowDirections = UIPopoverArrowDirectionLeft;
presentationController.sourceView = containerFrameOfReferenceView;
// arrow points out of the rect specified here
presentationController.sourceRect = childOfContainerView.frame;
Run Code Online (Sandbox Code Playgroud)

但你也想解雇这个.要在不使用代理的情况下执行此操作,您的演示控制器只需调用:

[self dismissViewControllerAnimated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

但是,如果我旋转我的设备,并且弹出窗口没有指向正确的区域呢?您的演示控制器可以处理它:

// Respond to rotations or split screen changes
- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [coordinator animateAlongsideTransition:nil 
                                 completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
        // Fix up popover placement if necessary, after the transition.
        if (self.presentedViewController) {
            UIPopoverPresentationController *presentationController =
                    [self.presentedViewController popoverPresentationController];
            presentationController.sourceView = containerFrameOfReferenceView;
            presentationController.sourceRect = childOfContainerView.frame;
        }
    }];
}
Run Code Online (Sandbox Code Playgroud)