如何更正UIPopoverController是不推荐使用的警告消息?

我正在使用此代码的代码

mediaLibraryPopover = [[UIPopoverController alloc] initWithContentViewController:avc]; [self.mediaLibraryPopover presentPopoverFromRect:[theButton bounds] inView:theButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 

我在Xcode-7中得到这个警告。

 UIPopoverController is deprecated ,first deprecated in iOS 9.0 - UIPopoverController is deprecated. Popovers are now implemented as UIViewController presentations. Use a modal presentation style of UIM 

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

您可以使用以下代码:

 avc.modalPresentationStyle = UIModalPresentationPopover; avc.popoverPresentationController.sourceView = theButton; [self presentViewController:avc animated:YES completion:nil]; 

UIModalPresentationPopover

在横向常规的环境中,在popup视图中显示内容的呈现样式。 背景内容变暗,在popup窗口之外点击导致popup窗口被解除。 如果您不想点击closurespopup窗口,则可以将一个或多个视图分配给关联UIPopoverPresentationController对象的passthroughViews属性,您可以从popoverPresentationController属性获取该对象。

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

在iOS 8.0及更高版本中可用。

参考UIModalPresentationStyle参考


您需要设置sourceViewbarButtonItem属性,否则会崩溃,并显示以下消息:

***终止应用程序,由于未捕获的exception“NSGenericException”,原因:'UIPopoverPresentationController(***)应该有一个非nil sourceView或barButtonItem设置演示之前。

要正确地锚定popup窗口箭头,还需要指定sourceRect属性。

 avc.modalPresentationStyle = UIModalPresentationPopover; avc.popoverPresentationController.sourceView = self.view; avc.popoverPresentationController.sourceRect = theButton.frame; [self presentViewController:avc animated:YES completion:nil]; 

有关更多详细信息,请参阅sourceView和sourceRect 。

苹果有官方的方式来呈现和configurationiOS8的popup窗口在这里: https : //developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationController_class/index.html

虽然类似@ MidhunMP的回答,但值得注意的是这个段落:

在调用presentViewController:animated:completion:之后configurationpresentViewController:animated:completion:表示控制器presentViewController:animated:completion:看起来可能与直觉相反,但是直到启动演示文稿之后,UIKit才会创build表示控制器。 另外,UIKit必须等到下一个更新周期才能在屏幕上显示新的内容。 这种延迟使您有时间为您的popup窗口configuration演示控制器。

如果需要,configuration和响应事件也可以通过委托来完成( 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; 

但是你也想解雇这个。 要做到这一点而不使用委托,您的呈现控制器可以调用:

 [self dismissViewControllerAnimated:YES completion:nil]; 

但是,如果我旋转我的设备,并且popup不指向正确的区域? 您的演示控制器可以处理它:

 // 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; } }]; } 

如果想直接从button操作,那么这个代码可以使用

 SecondViewController *destinationViewController = (SecondViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"second"]; destinationViewController.modalPresentationStyle = UIModalPresentationPopover; destinationViewController.popoverPresentationController.sourceView = self.customButton; // Set the correct sourceRect given the sender's bounds destinationViewController.popoverPresentationController.sourceRect = ((UIView *)sender).bounds; [self presentViewController:destinationViewController animated:YES completion:nil]; 

编辑:关于反对票。 首先是一个有趣和相关的故事:

http://www.folklore.org/StoryView.py?story=Negative_2000_Lines_Of_Code.txt

我发布了下面的答案,以帮助编程人员在iPad / iPhone呈现媒体select器UI时仍然需要单独的执行path。 在我原来的post时,这在其他答案中还不清楚。 这个解决schemepath简化了我的代码和将来的维护我的应用程序。 我认为其他人可能会觉得这个观点很有用,因为有时删除正确的代码行可能是一个很好的解决scheme。

编辑结束。

如果你已经有一个工作程序,只是想摆脱折旧的警告这可以为你工作。

在我的代码中,在我的理解中,Popovers是为iPad而推出的,并且是iPad专用的。 苹果似乎已经改变了这一点。 所以,如果你已经有一个使用这样的工作程序:

 if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) // use popovers else // don't use popovers 

你可以做的只是摆脱iPad特定的代码(这可能是使用Popovers的代码),让你的程序运行iPhone和iPad的相同的说明。 这对我有效。