web-dev-qa-db-fra.com

UIPopoverPresentationController sur iPhone ne produit pas de popover

J'essaie d'implémenter la nouvelle UIPopoverPresentationController dans mon application iPhone (avec Objective C). Ce que je veux, c'est un simple popover avec une table qui émane du bouton de lancement.

--Modifier--

Voici monRÉVISÉcode, adapté de la recherche dans la documentation, SO, et de l'entrée dans les commentaires ci-dessous:

- (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;

Voici mon branchement de storyboard:

enter image description here

Cependant, ceci présente simplement une vue de table de manière modale, remontant du bas et consommant la totalité de l'écran.

J'ai cherché sur Google, et j'ai regardé partout SO, mais il semble que je ne suis pas le seul à être confondu par ce que je pensais pouvoir résoudre un problème compliqué pour l'iPhone.

Quelqu'un peut-il voir un problème dans mon code ou me diriger vers un tutoriel clair? J'ai regardé, mais peut-être que l'API est tellement nouvelle que personne ne l'a encore maîtrisé.

Merci!

2ème édition:

Voici ce qui est présenté à la suite du code ci-dessus. J'ai réduit la taille de la vue de table dans le View Controller Je m'attendais à être présenté comme un popover. J'ai coloré le fond gris, juste pour clarifier ce qui apparaît plutôt que le popover.

enter image description here

27
rattletrap99

Pas:

A) Liez votre UIButton au contrôleur de vue de la fenêtre popover à l'aide du type de séquence Present As Popover. En fait, j'ai dû créer un nouveau projet pour que cela apparaisse, mais c'est probablement quelque chose à voir avec le SDK de base.

B) Assurez-vous que le contrôleur de vue contenant la UIButton soit conforme au <UIPopoverPresentationControllerDelegate>. Par exemple. Dans votre fichier MyViewController.m, ajoutez:

@interface MyViewController () <UIPopoverPresentationControllerDelegate>

C) Ajoutez la méthode ci-dessous au contrôleur de vue contenant la UIButton:

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {

    return UIModalPresentationNone;
}

D) Ajoutez ce qui suit dans votre prepareForSegue:sender: en remplaçant votre chèque segue.identifier:

if ([segue.identifier isEqualToString:@"CatSelectSegue"]) {
    UIViewController *dvc = segue.destinationViewController;
    UIPopoverPresentationController *controller = dvc.popoverPresentationController;
    if (controller) {
        controller.delegate = self;
    }
}

Code testé et la preuve que cela fonctionne:

Popover on iPhone without 3rd Party Controls

Edit: Mon fichier TPOPViewController.m de l'application de test où la magie opère:

#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

Mon scénario de test également:

Popover on iPhone test storyboard

71
Robotic Cat

Apparemment, la méthode ci-dessus ne fonctionne plus avec iOS9/Xcode7 . En effet, si vous définissez le style de division sur "Popover" à l'aide d'Interface Builder, Xcode l'ignore lorsqu'il compile votre application. De plus, il rétablit automatiquement le passage à "Push" la prochaine fois que vous ouvrez votre projet. Si vous avez un logiciel de contrôle de version comme Git, vous pourrez observer ces modifications indésirables.

Cependant, il est toujours possible d'obtenir des popovers de style iPad sur l'iPhone si vous (manuellement} _ présentez le contrôleur de vue que vous souhaitez afficher sous la forme d'une popover. Exemple de code 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)
    }

}
18
bhnascar

Swift 3.X

Cela montrera le popover au centre de l'écran

class CommonViewController: UIViewController, UIPopoverPresentationControllerDelegate{

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

func showPopover(){
    let storyboard = UIStoryboard(name: "Pickers", bundle: nil)
    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 = .init(rawValue: 0)
    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
}
4
tsik

Pour présenter UIModalPresentationStyle popover à partir d'un iPhone/iPad:

-(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;
}
0
Harshal Wani