web-dev-qa-db-fra.com

UIPopoverPresentationController sur iOS 8 iPhone

Est-ce que quelqu'un sait si UIPopoverPresentationController peut être utilisé pour présenter des popovers sur des iPhones? Vous vous demandez si Apple a ajouté cette fonctionnalité sur iOS 8 dans le but de créer un contrôleur de présentation plus unifié pour iPad et iPhone.

Pas sûr que ce soit OK pour poser/répondre aux questions de Beta. Je vais l'enlever dans ce cas.

73
Dave

Vous pouvez remplacer le comportement adaptatif par défaut (UIModalPresentationFullScreen dans un environnement horizontal compact, c’est-à-dire un iPhone) à l’aide de la commande adaptivePresentationStyleForPresentationController: méthode disponible via UIPopoverPresentationController.delegate.

UIPresentationController utilise cette méthode pour demander le nouveau style de présentation à utiliser. Dans ce cas, le simple retour de UIModalPresentationNone entraînera le rendu de UIPopoverPresentationController sous forme de popover au lieu de plein écran.

Voici un exemple de popover utilisant une configuration de séquence dans le storyboard d’un UIBarButtonItem à " présent par modale " un UIViewController

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
    }
}

Cette astuce a été mentionnée dans session WWDC 2014 214 "Progression du contrôleur de visualisation dans iOS8" (36:30).

83
Ivan Choo

Si quelqu'un veut présenter un popover avec du code uniquement, vous pouvez utiliser l'approche suivante.

OBJECTIF - C

Déclarez une propriété de UIPopoverPresentationController:

@property(nonatomic,retain)UIPopoverPresentationController *dateTimePopover8;

Utilisez la méthode suivante pour présenter le popover d'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];
}

Utilisez la méthode suivante pour présenter le popover d'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];
}

Implémentez également cette méthode déléguée dans votre contrôleur de vue:

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

Pour ignorer cette fenêtre, il suffit de fermer le contrôleur de vue. Voici le code pour fermer le contrôleur de vue:

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

rapide

Utilisez la méthode suivante pour présenter le popover d'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)
    }

Utilisez la méthode suivante pour présenter le popover d'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)
    }

Implémentez également cette méthode déléguée dans votre contrôleur de vue:

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

Assurez-vous d’ajouter un délégué UIPopoverPresentationControllerDelegate dans le fichier .h/.m/.Swift

73
Desert Rose

PROBLEME: La popover de l'iPhone affiche le plein écran et ne respecte pas la valeur preferredContentSize.

SOLUTION: Contrairement à ce que Apple suggère dans la référence de classe UIPopoverPresentationController, présentant le contrôleur de vue après obtenir une référence au contrôleur de présentation popover et le configurer.

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

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

J'ai trouvé une solution de contournement.

Sur Xcode6.1, utilisez presentationController.delegate au lieu de 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;
}

Dans WWDC 2014, "Afficher les progrès du contrôleur dans iOS8", les codes ci-dessous peuvent s'afficher sur l'iPhone.

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

Mais sur Xcode 6.1, ces codes affichent la présentation FullScreen ... (nvc.popoverPresentationController est nul)

Je doute que cela puisse être un bug d'Apple.

2
nomadmonad

Assurez-vous de mettre en œuvre IAdaptivePresentationControllerDelegate

comme ça:

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

Si vous ne voulez pas de popovers en plein écran

2
ader

Dans iOS 8.3 et versions ultérieures, utilisez la syntaxe suivante dans le protocole UIPopoverPresentationControllerDelegate pour remplacer le UIModalPresentationStyle de votre popup.

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

ajoutez ces deux méthodes dans votre classe WEBVIEW. et ajouter

-(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;
}
0
Mongo db