ios iPhone 上的 UIPopoverPresentationController 不会产生弹出窗口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28521583/
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
UIPopoverPresentationController on iPhone doesn't produce popover
提问by rattletrap99
I'm trying to implement the new UIPopoverPresentationController
in my iPhone app (using Objective C). What I want is a simple popover with a tableview that emanates from the initiating button.
我正在尝试UIPopoverPresentationController
在我的 iPhone 应用程序中实现新功能(使用 Objective C)。我想要的是一个简单的弹出窗口,带有一个从启动按钮发出的表格视图。
--Edit--
- 编辑 -
Here's my REVISEDcode, adapted from research in the docs, SO, and from input in comments below:
这里是我的REVISED代码,改编自研究在该文档中,SO,并从输入如下意见:
- (IBAction)selectCategoryBtn:(UIButton *)sender
{
[self performSegueWithIdentifier:@"CatSelectSegue" sender:self.selCatButton];
}
-(void) prepareForSegue:(UIStoryboardSegue *) segue Sender:(id) sender
{
if (sender == self.selCatButton)
{
if ([segue.identifier isEqualToString:@"CatSelectSegue"])
{
UIPopoverPresentationController *controller = segue.destinationViewController;
controller.delegate = self;
controller.sourceView = self.selCatButton;
controller.sourceRect = self.selCatButton.frame;
}
}
}
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return UIModalPresentationNone;
Here's my storyboard hookup:
这是我的故事板连接:
However this simply presents a tableview in a modal fashion, rising up from the bottom and consuming the entire screen.
然而,这只是以模态方式呈现一个 tableview,从底部上升并消耗整个屏幕。
I've googled, and looked all over SO, but it appears that I'm not the only one confused by what I'd hoped would resolve a nettlesome issue for the iPhone.
我已经用谷歌搜索过,并查看了所有内容,但似乎我并不是唯一一个对我希望解决 iPhone 令人烦恼的问题感到困惑的人。
Can anyone see a glitch in my code or direct me to a clear tutorial? I've looked, but maybe the API is just so new nobody's got a handle on it yet.
任何人都可以看到我的代码中的故障或将我引导到清晰的教程吗?我已经看过了,但也许 API 太新了,还没有人掌握它。
Thanks!
谢谢!
2nd edit:
第二次编辑:
Here's what gets presented as a result of the code above. I reduced the size of the tableview in the View Controller I expected to be presented as a popover. I colored the background gray, just to clarify what's showing up instead of the popover.
以下是上述代码的结果。我减小了 View Controller 中 tableview 的大小,我希望以弹出框的形式呈现。我将背景涂成灰色,只是为了澄清显示的是什么而不是弹出框。
回答by Robotic Cat
Steps:
脚步:
A) Link your UIButton
to the popover's view controller using the Present As Popover
segue type. I actually had to create a new project to get this to appear but it's probably something to do with the base SDK.
A)UIButton
使用Present As Popover
segue 类型将您的链接到 popover 的视图控制器。我实际上必须创建一个新项目才能显示它,但这可能与基础 SDK 有关。
B) Make the View Controller containing the UIButton
conform to the <UIPopoverPresentationControllerDelegate>
. E.g. In your MyViewController.m
file add:
B) 使包含UIButton
符合<UIPopoverPresentationControllerDelegate>
. 例如在您的MyViewController.m
文件中添加:
@interface MyViewController () <UIPopoverPresentationControllerDelegate>
C) Add the method below to the View Controller containing the UIButton
:
C) 将下面的方法添加到包含以下内容的视图控制器中UIButton
:
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
D) Add the following into your prepareForSegue:sender:
replacing your segue.identifier
check:
D) 将以下内容添加到您的prepareForSegue:sender:
替换segue.identifier
支票中:
if ([segue.identifier isEqualToString:@"CatSelectSegue"]) {
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *controller = dvc.popoverPresentationController;
if (controller) {
controller.delegate = self;
}
}
Code tested and proof it works:
代码测试并证明它有效:
Edit: My test app TPOPViewController.m file where the magic happens:
编辑:我的测试应用程序 TPOPViewController.m 文件发生神奇之处:
#import "TPOPViewController.h"
@interface TPOPViewController () <UIPopoverPresentationControllerDelegate>//, UIAdaptivePresentationControllerDelegate>
@end
@implementation TPOPViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString *identifier = segue.identifier;
if ([identifier isEqualToString:@"popover"]) {
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *ppc = dvc.popoverPresentationController;
if (ppc) {
if ([sender isKindOfClass:[UIButton class]]) { // Assumes the popover is being triggered by a UIButton
ppc.sourceView = (UIButton *)sender;
ppc.sourceRect = [(UIButton *)sender bounds];
}
ppc.delegate = self;
}
}
}
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
@end
My test storyboard as well:
我的测试故事板也是:
回答by bhnascar
Apparently the above method no longer works with iOS9/Xcode7. This is because if you set the segue style to "Popover" using Interface Builder, Xcode ignores it when it compiles your application. Furthermore, it automatically sets the segue back to "Push" the next time you open your project. If you have version control software like Git, you'll be able to observe this unwanted change being made.
显然上述方法不再适用于iOS9/Xcode7。这是因为如果您使用 Interface Builder 将 segue 样式设置为“Popover”,Xcode 在编译您的应用程序时会忽略它。此外,它会在您下次打开项目时自动将转场设置回“推送”。如果您有像 Git 这样的版本控制软件,您将能够观察到这种不需要的更改。
However, it's still possible to get iPad-style popovers on the iPhone if you manuallypresent the view controller that you want to show as a popover. Example Swift code:
但是,如果您手动呈现要显示为弹出框的视图控制器,仍然可以在 iPhone 上获得 iPad 样式的弹出框。示例 Swift 代码:
// ViewController.swift
// PopoverDemo
//
// Created by bhnascar on 12/2/15.
// Copyright ? 2015 bhnascar. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
/* The bar button item that will present the popover. */
var popoverButton: UIBarButtonItem?
override func viewDidLoad() {
super.viewDidLoad()
popoverButton = UIBarButtonItem(title: "Pop!", style: UIBarButtonItemStyle.Plain, target: self, action: "presentPopover")
self.navigationItem.rightBarButtonItem = popoverButton
}
// Mark: - UIPopoverPresentationControllerDelegate
func prepareForPopoverPresentation(popoverPresentationController: UIPopoverPresentationController) {
popoverPresentationController.permittedArrowDirections = .any
popoverPresentationController.barButtonItem = popoverButton
}
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
// Mark: - Callback function for popover button.
func presentPopover() {
let popoverContentController = UIViewController()
popoverContentController.view.backgroundColor = .blue
// Set your popover size.
popoverContentController.preferredContentSize = CGSize(width: 300, height: 300)
// Set the presentation style to modal so that the above methods get called.
popoverContentController.modalPresentationStyle = .popover
// Set the popover presentation controller delegate so that the above methods get called.
popoverContentController.popoverPresentationController!.delegate = self
// Present the popover.
self.present(popoverContentController, animated: true, completion: nil)
}
}
回答by tsik
SWIFT 3.X
斯威夫特 3.X
This will show the popover at the center of the screen
这将在屏幕中央显示弹出框
class CommonViewController: UIViewController, UIPopoverPresentationControllerDelegate{
func adaptivePresentationStyle(
for controller: UIPresentationController,
traitCollection: UITraitCollection)
-> UIModalPresentationStyle {
return .none
}
func showPopover() {
let myViewController = UIViewController()
myViewController.preferredContentSize = CGSize(width: 320, height: 200)
myViewController.modalPresentationStyle = .popover
let popOver = myViewController.popoverPresentationController
popOver?.delegate = self
self.present(myViewController, animated: true, completion: nil)
popOver?.permittedArrowDirections = .up
popOver?.sourceView = self.view
let rect = CGRect(
origin: CGPoint(x: self.view.frame.width/2,
y: self.view.frame.height/2),
size: CGSize(width: 1, height: 1)
)
popOver?.sourceRect = rect
}
}
回答by Harshal Wani
To present UIModalPresentationStyle popover from iPhone/iPad:
从 iPhone/iPad 呈现 UIModalPresentationStyle 弹出框:
-(void)menuButtonPressed:(UIButton *)sender {
self.menuPopoverController = [[DownloadMenuPopoverController alloc] initWithStyle:UITableViewStylePlain];
self.menuPopoverController.delegate = self;
self.menuPopoverController.modalPresentationStyle = UIModalPresentationPopover;
self.menuPopoverController.popoverPresentationController.delegate = self;
self.menuPopoverController.preferredContentSize = CGSizeMake(250,80);
self.menuPopoverController.popoverPresentationController.sourceRect = sender.frame;// rect to show view
self.menuPopoverController.popoverPresentationController.sourceView = self.view;
UIPopoverPresentationController *popPC = self.menuPopoverController.popoverPresentationController;
popPC.permittedArrowDirections = UIPopoverArrowDirectionAny;
popPC.delegate = self;
[self presentViewController:self.menuPopoverController animated:YES completion:nil];
}
#pragma mark - UIPresentationController Delegate methods
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
return UIModalPresentationNone;
}
- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style {
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller.presentedViewController];
return navController;
}