ios 如何修复“UIPopoverController is deprecated”警告?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32818297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I fix the "UIPopoverController is deprecated" warning?
提问by Varun Naharia
I am using this code:
我正在使用此代码:
mediaLibraryPopover = [[UIPopoverController alloc]
initWithContentViewController:avc];
[self.mediaLibraryPopover presentPopoverFromRect:[theButton bounds]
inView:theButton
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
And I am getting this warning in Xcode 7:
我在 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 UIModalPresentationPopover and UIPopoverPresentationController.
UIPopoverController 已弃用,首先在 iOS 9.0 中弃用 - UIPopoverController 已弃用。Popovers 现在实现为 UIViewController 演示文稿。使用 UIModalPresentationPopover 和 UIPopoverPresentationController 的模态呈现风格。
回答by Midhun MP
You no longer need UIPopoverController
for presenting a view controller.
Instead you can set the modalPresentationStyle
of view controller to UIModalPresentationPopover
.
您不再需要UIPopoverController
呈现视图控制器。相反,您可以将modalPresentationStyle
of 视图控制器设置为UIModalPresentationPopover
.
You can use the following code for that:
您可以使用以下代码:
avc.modalPresentationStyle = UIModalPresentationPopover;
avc.popoverPresentationController.sourceView = theButton;
[self presentViewController:avc animated:YES completion:nil];
UIModalPresentationPopover
In a horizontally regular environment, a presentation style where the content is displayed in a popover view. The background content is dimmed and taps outside the popover cause the popover to be dismissed. If you do not want taps to dismiss the popover, you can assign one or more views to the passthroughViews property of the associated UIPopoverPresentationController object, which you can get from the popoverPresentationController property.
In a horizontally compact environment, this option behaves the same as UIModalPresentationFullScreen.
Available in iOS 8.0 and later.
UIModalPresentationPopover
在水平规则的环境中,在弹出视图中显示内容的呈现样式。背景内容变暗,点击弹出框外会导致弹出框消失。如果您不想点击关闭弹出框,您可以将一个或多个视图分配给关联的 UIPopoverPresentationController 对象的 passthroughViews 属性,您可以从 popoverPresentationController 属性中获取该属性。
在水平紧凑的环境中,此选项的行为与 UIModalPresentationFullScreen 相同。
在 iOS 8.0 及更高版本中可用。
Reference UIModalPresentationStyle Reference
You need to set either sourceView
or barButtonItem
property, else it will crash with the following message:
您需要设置sourceView
或barButtonItem
属性,否则它将崩溃并显示以下消息:
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'UIPopoverPresentationController (***) should have a non-nil sourceView or barButtonItem set before the presentation occurs.'
*** 由于未捕获的异常“NSGenericException”而终止应用程序,原因:“UIPopoverPresentationController (***) 应该在演示发生之前设置一个非零的 sourceView 或 barButtonItem。”
For anchoring the popover arrow correctly, you need to specify the sourceRect
property also.
为了正确锚定弹出箭头,您还需要指定sourceRect
属性。
avc.modalPresentationStyle = UIModalPresentationPopover;
avc.popoverPresentationController.sourceView = self.view;
avc.popoverPresentationController.sourceRect = theButton.frame;
[self presentViewController:avc animated:YES completion:nil];
Refer sourceViewand sourceRectfor more details.
有关更多详细信息,请参阅sourceView和sourceRect。
回答by qix
Apple has the official way to present and configure popovers for iOS8 here: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationController_class/index.html
Apple 在此处提供了为 iOS8 呈现和配置弹出框的官方方法:https: //developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationController_class/index.html
While similar to @MidhunMP's answer, it's worth noting the paragraph:
虽然类似于@MidhunMP 的回答,但值得注意的是该段:
Configuring the popover presentation controller after calling
presentViewController:animated:completion:
might seem counter-intuitive but UIKit does not create a presentation controller until after you initiate a presentation. In addition, UIKit must wait until the next update cycle to display new content onscreen anyway. That delay gives you time to configure the presentation controller for your popover.
在调用之后配置 popover 呈现控制器
presentViewController:animated:completion:
可能看起来违反直觉,但 UIKit 直到您启动呈现后才会创建呈现控制器。此外,无论如何,UIKit 必须等到下一个更新周期才能在屏幕上显示新内容。这个延迟让你有时间为你的弹出框配置演示控制器。
Configuration and responding to events can also be done via a delegate if you wanted (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationControllerDelegate_protocol/index.html).
如果您愿意,也可以通过委托进行配置和响应事件(https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationControllerDelegate_protocol/index.html)。
An example, setting aside the use of the delegate:
一个例子,搁置委托的使用:
// 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;
But you'll also want to dismiss this. To do so without using a delegate, your presenting controller can just call:
但你也会想忽略这一点。要在不使用委托的情况下这样做,您的呈现控制器只需调用:
[self dismissViewControllerAnimated:YES completion:nil];
But what if I rotate my device, and the popover doesn't point to the right area? Your presenting controller can handle it:
但是如果我旋转我的设备,并且弹出框没有指向正确的区域怎么办?您的演示控制器可以处理它:
// 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;
}
}];
}
回答by Abhishek
If wanted directly from Button Action then this code can be used
如果直接从按钮操作中想要,则可以使用此代码
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];
回答by Mark Nilsen
EDIT: Regarding the down-votes. First a fun and relevant story:
编辑:关于否决票。首先是一个有趣且相关的故事:
http://www.folklore.org/StoryView.py?story=Negative_2000_Lines_Of_Code.txt
http://www.folklore.org/StoryView.py?story=Negative_2000_Lines_Of_Code.txt
I posted the answer below in order to help coders that might have been stuck in the mindset that iPad/iPhone still needed separate execution paths when presenting a media picker UI.At the time of my original post this was not clear in the other answers. This solution path simplified my code and the future maintenance of my App. I think others might find this perspective useful because sometimes removing the right lines of code can be a good solution.
我在下面发布了答案,以帮助可能陷入 iPad/iPhone 在呈现媒体选择器 UI 时仍需要单独执行路径的心态的编码人员。在我发表原始帖子时,其他答案中还不清楚这一点。这个解决方案路径简化了我的代码和我的应用程序的未来维护。我认为其他人可能会发现这个观点很有用,因为有时删除正确的代码行可能是一个很好的解决方案。
End of edit.
编辑结束。
If you already have a working program and just want to get rid of the depreciation warning this could work for you.
如果您已经有一个可以运行的程序并且只想摆脱折旧警告,这可能对您有用。
In my code, and in my understanding, Popovers were introduced for the iPad and are iPad specific. Apple seems to have changed that. So, if you already have a working program that uses something like this:
在我的代码中,在我的理解中,弹出窗口是为 iPad 引入的,并且是特定于 iPad 的。苹果似乎已经改变了这一点。因此,如果您已经有一个使用以下内容的工作程序:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
// use popovers
else
// don't use popovers
what you can do is just get rid of the iPad specific code (which is probably the code using Popovers) and have your program run the same instructions for both iPhone and iPad. This worked for me.
你能做的就是去掉 iPad 特定的代码(这可能是使用 Popovers 的代码),让你的程序为 iPhone 和 iPad 运行相同的指令。这对我有用。