objective-c iOS 8 iPhone 上的 UIPopoverPresentationController

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25319179/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:24:54  来源:igfitidea点击:

UIPopoverPresentationController on iOS 8 iPhone

objective-ciphoneuipopovercontrollerios8uipopover

提问by Dave

Does anyone know if UIPopoverPresentationControllercan be used to present popovers on iPhones? Wondering if Apple added this feature on iOS 8 in their attempt to create a more unified presentation controllers for iPad and iPhone.

有谁知道是否UIPopoverPresentationController可以用来在 iPhone 上呈现弹出窗口?想知道 Apple 是否在 iOS 8 上添加了此功能,以尝试为 iPad 和 iPhone 创建更统一的演示控制器。

Not sure if its OK to ask/answer questions from Beta. I will remove it in that case.

不确定从 Beta 版提问/回答问题是否可以。在这种情况下,我会删除它。

回答by Ivan Choo

You can override the default adaptive behaviour (UIModalPresentationFullScreenin compact horizontal environment, i.e. iPhone) using the adaptivePresentationStyleForPresentationController:method available through UIPopoverPresentationController.delegate.

您可以UIModalPresentationFullScreen使用 adaptivePresentationStyleForPresentationController:通过UIPopoverPresentationController.delegate.

UIPresentationControlleruses this method to ask the new presentation style to use, which in your case, simply returning UIModalPresentationNonewill cause the UIPopoverPresentationControllerto render as a popover instead of fullscreen.

UIPresentationController使用此方法要求使用新的演示文稿样式,在您的情况下,简单地返回UIModalPresentationNone将导致UIPopoverPresentationController呈现为弹出窗口而不是全屏。

Here's an example of the popover using a segue setup in storyboard from a UIBarButtonItemto "present modally" a UIViewController

这是一个使用故事板中的 segue 设置的 popover 示例,从 aUIBarButtonItem到“模态呈现” aUIViewController

class SomeViewController: UIViewController, UIPopoverPresentationControllerDelegate {

    // override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { // swift < 3.0
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "PopoverSegue" {
            if let controller = segue.destinationViewController as? UIViewController {
                controller.popoverPresentationController.delegate = self
                controller.preferredContentSize = CGSize(width: 320, height: 186)                
            }
        }
    }

    // MARK: UIPopoverPresentationControllerDelegate

    //func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!) -> UIModalPresentationStyle { // swift < 3.0
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        // Return no adaptive presentation style, use default presentation behaviour
        return .None
    }
}

This trick was mentioned in WWDC 2014 session 214 "View Controller Advancement in iOS8"(36:30)

这个技巧在WWDC 2014 session 214 "View Controller Advancement in iOS8"(36:30)中提到

回答by Desert Rose

If anybody wants to present a popover with code only, you can use the following approach.

如果有人只想用代码呈现弹出窗口,您可以使用以下方法。

OBJECTIVE - C

目标 - C

Declare a property of UIPopoverPresentationController:

声明一个属性UIPopoverPresentationController

@property(nonatomic,retain)UIPopoverPresentationController *dateTimePopover8;

Use the following method to present the popover from UIButton:

使用以下方法从 UIButton 呈现弹出窗口:

- (IBAction)btnSelectDatePressed:(id)sender
{
    UINavigationController *destNav = [[UINavigationController alloc] initWithRootViewController:dateVC];/*Here dateVC is controller you want to show in popover*/
    dateVC.preferredContentSize = CGSizeMake(280,200);
    destNav.modalPresentationStyle = UIModalPresentationPopover;
    _dateTimePopover8 = destNav.popoverPresentationController;
    _dateTimePopover8.delegate = self;
    _dateTimePopover8.sourceView = self.view;
    _dateTimePopover8.sourceRect = sender.frame;
    destNav.navigationBarHidden = YES;
    [self presentViewController:destNav animated:YES completion:nil];
}

Use the following method to present the popover from UIBarButtonItem:

使用以下方法从 UIBarButtonItem 呈现弹出窗口:

- (IBAction)btnSelectDatePressed:(id)sender
{
    UINavigationController *destNav = [[UINavigationController alloc] initWithRootViewController:dateVC];/*Here dateVC is controller you want to show in popover*/
    dateVC.preferredContentSize = CGSizeMake(280,200);
    destNav.modalPresentationStyle = UIModalPresentationPopover;
    _dateTimePopover8 = destNav.popoverPresentationController;
    _dateTimePopover8.delegate = self;
    _dateTimePopover8.sourceView = self.view;
     CGRect frame = [[sender valueForKey:@"view"] frame];
    frame.origin.y = frame.origin.y+20;
    _dateTimePopover8.sourceRect = frame;
    destNav.navigationBarHidden = YES;
    [self presentViewController:destNav animated:YES completion:nil];
}

Implement this delegate method too in your view controller:

在你的视图控制器中也实现这个委托方法:

- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller {
    return UIModalPresentationNone;
}

To dismiss this popover, simply dismiss the view controller. Below is the code to dismiss the view controller:

要关闭此弹出框,只需关闭视图控制器即可。下面是关闭视图控制器的代码:

-(void)hideIOS8PopOver
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

SWIFT

迅速

Use the following method to present the popover from UIButon:

使用以下方法从 UIButon 呈现弹出窗口:

func filterBooks(sender: UIButon)
    {
        let filterVC =  FilterDistanceViewController(nibName: "FilterDistanceViewController", bundle: nil)
        var filterDistanceViewController = UINavigationController(rootViewController: filterVC)
        filterDistanceViewController.preferredContentSize = CGSizeMake(300, 205)
        let popoverPresentationViewController = filterDistanceViewController.popoverPresentationController
        popoverPresentationViewController?.permittedArrowDirections = .Any
        popoverPresentationViewController?.delegate = self
        popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem
        popoverPresentationViewController!.sourceView = self.view;
        popoverPresentationViewController!.sourceRect = sender.frame

        filterDistanceViewController.modalPresentationStyle = UIModalPresentationStyle.Popover
        filterDistanceViewController.navigationBarHidden = true
        self.presentViewController(filterDistanceViewController, animated: true, completion: nil)
    }

Use the following method to present the popover from UIBarButtonItem:

使用以下方法从 UIBarButtonItem 呈现弹出窗口:

func filterBooks(sender: UIBarButtonItem)
    {
        let filterVC =  FilterDistanceViewController(nibName: "FilterDistanceViewController", bundle: nil)
        var filterDistanceViewController = UINavigationController(rootViewController: filterVC)
        filterDistanceViewController.preferredContentSize = CGSizeMake(300, 205)
        let popoverPresentationViewController = filterDistanceViewController.popoverPresentationController
        popoverPresentationViewController?.permittedArrowDirections = .Any
        popoverPresentationViewController?.delegate = self
        popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem
        popoverPresentationViewController!.sourceView = self.view;
        var frame:CGRect = sender.valueForKey("view")!.frame
        frame.origin.y = frame.origin.y+20
        popoverPresentationViewController!.sourceRect = frame

        filterDistanceViewController.modalPresentationStyle = UIModalPresentationStyle.Popover
        filterDistanceViewController.navigationBarHidden = true
        self.presentViewController(filterDistanceViewController, animated: true, completion: nil)
    }

Implement this delegate method too in your view controller:

在你的视图控制器中也实现这个委托方法:

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle{
        return .None
    }

Please make sure to add delegate UIPopoverPresentationControllerDelegatein .h/.m/.swift file

请确保UIPopoverPresentationControllerDelegate在 .h/.m/.swift 文件中添加委托

回答by agandi

PROBLEM:iPhone popover displays fullscreen and does not respect preferredContentSize value.

问题:iPhone 弹出窗口显示全屏并且不遵守 preferredContentSize 值。

SOLUTION:Contrary to what Apple suggests in the UIPopoverPresentationController Class reference, presenting the view controller aftergetting a reference to the popover presentation controller and configuring it.

解决方案:与 Apple 在 UIPopoverPresentationController 类参考中的建议相反,在获取对 popover 呈现控制器的引用并对其进行配置呈现视图控制器。

// Get the popover presentation controller and configure it.
//...

// Present the view controller using the popover style.
[self presentViewController:myPopoverViewController animated: YES completion: nil]; 

回答by ader

Make sure to implement UIAdaptivePresentationControllerDelegate

确保实现UIAdaptivePresentationControllerDelegate

like this:

像这样:

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
    return UIModalPresentationNone;
}

If you don't want full-screen popovers

如果你不想全屏弹出

回答by nomadmonad

I've found some workaround.

我找到了一些解决方法。

On Xcode6.1, use presentationController.delegateinstead of popoverPresentationController.delegate.

在 Xcode6.1 上,使用presentationController.delegate代替popoverPresentationController.delegate.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier compare:@"showPopOver"] == NSOrderedSame) {
        UINavigationController * nvc = segue.destinationViewController;
        UIPresentationController * pc = nvc.presentationController;
        pc.delegate = self;
    }
}

#pragma mark == UIPopoverPresentationControllerDelegate ==
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
    return UIModalPresentationNone;
}

In WWDC 2014 "View Controller Advancements in iOS8", below codes can show popover on iPhone.

在 WWDC 2014 "View Controller Advancements in iOS8" 中,下面的代码可以在 iPhone 上显示 popover。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{

    UINavigationController * nvc = segue.destinationViewController;
    UIPopoverPresentationController * pvc = nvc.popoverPresentationController;
    pvc.delegate = self;
}

#pragma mark == UIPopoverPresentationControllerDelegate ==
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
    return UIModalPresentationNone;
}

But On Xcode 6.1, these codes shows FullScreen presentation... (nvc.popoverPresentationController is nil)

但是在 Xcode 6.1 上,这些代码显示全屏演示......(nvc.popoverPresentationController 为零)

I doubt it might be an Apple's bug.

我怀疑这可能是Apple的错误。

回答by adaria

In iOS 8.3 and later, use the following syntax in the UIPopoverPresentationControllerDelegateprotocol to override your popup's UIModalPresentationStyle.

在 iOS 8.3 及更高版本中,在UIPopoverPresentationControllerDelegate协议中使用以下语法来覆盖弹出窗口的UIModalPresentationStyle.

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
    return .none
}

回答by Mongo db

add these two methods in your WEBVIEW class. and add

在 WEBVIEW 类中添加这两个方法。并添加

-(void) prepareForSegue: (UIStoryboardSegue * ) segue sender: (id) sender {
    // Assuming you've hooked this all up in a Storyboard with a popover presentation style
    if ([segue.identifier isEqualToString: @"showPopover"]) {
        UINavigationController * destNav = segue.destinationViewController;
        pop = destNav.viewControllers.firstObject;
        // This is the important part
        UIPopoverPresentationController * popPC = destNav.popoverPresentationController;
        popPC.delegate = self;
    }
}

- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller {
    return UIModalPresentationNone;
}