Comment présenter popover correctement dans iOS 8

J'essaie d'ajouter un UIPopoverView à mon application Swift iOS 8, mais je ne peux pas accéder à la propriété PopoverContentSize, car le popover ne s'affiche pas dans la forme correcte. mon code:

var popover: UIPopoverController? = nil 

    func addCategory() {

    var newCategory = storyboard.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
    var nav = UINavigationController(rootViewController: newCategory)
    popover = UIPopoverController(contentViewController: nav)
    popover!.setPopoverContentSize(CGSizeMake(550, 600), animated: true)
    popover!.delegate = self
    popover!.presentPopoverFromBarButtonItem(self.navigationItem.rightBarButtonItem, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}

La sortie:

entrez la description de l'image ici

Quand je fais la même chose via UIPopoverPresentationController, Je ne le fais toujours pas. c'est mon code:

func addCategory() {

    var popoverContent = self.storyboard.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
    var nav = UINavigationController(rootViewController: popoverContent)
    nav.modalPresentationStyle = UIModalPresentationStyle.Popover
    var popover = nav.popoverPresentationController as UIPopoverPresentationController
    popover.delegate = self
    popover.popoverContentSize = CGSizeMake(1000, 300)
    popover.sourceView = self.view
    popover.sourceRect = CGRectMake(100,100,0,0)

    self.presentViewController(nav, animated: true, completion: nil)

}

J'obtiens exactement la même sortie.

Comment personnaliser la taille de mon popover? Toute aide serait très apprécié!

104
demandé sur Joris416 2014-07-08 19:24:54

11 réponses

D'accord, un colocataire l'a regardé et l'a compris:

 func addCategory() {

    var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
    var nav = UINavigationController(rootViewController: popoverContent)
    nav.modalPresentationStyle = UIModalPresentationStyle.Popover
    var popover = nav.popoverPresentationController
    popoverContent.preferredContentSize = CGSizeMake(500,600)
    popover.delegate = self
    popover.sourceView = self.view
    popover.sourceRect = CGRectMake(100,100,0,0)

    self.presentViewController(nav, animated: true, completion: nil)

}

C'est le chemin.

Vous ne parlez plus au popover lui-même, vous parlez au contrôleur de vue à l'intérieur de celui-ci pour définir la taille du contenu, en appelant la propriété preferredContentSize

131
répondu Joris416 2014-12-24 18:39:33

En fait, c'est beaucoup plus simple que ça. Dans le storyboard, vous devez créer le viewcontroller que vous souhaitez utiliser comme popover et créer une classe viewcontroller comme d'habitude. Faites un segue comme indiqué ci-dessous à partir de l'objet que vous voulez ouvrir le popover, dans ce cas le UIBarButton nommé "Config".

entrez la description de l'image ici

Dans le" mother viewcontroller " implémentez le UIPopoverPresentationControllerDelegate et la méthode delegate:

func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
    //do som stuff from the popover
}

Remplacez la méthode prepareForSeque comme ceci:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     //segue for the popover configuration window
    if segue.identifier == "yourSegueIdentifierForPopOver" {
        if let controller = segue.destinationViewController as? UIViewController {
            controller.popoverPresentationController!.delegate = self
            controller.preferredContentSize = CGSize(width: 320, height: 186)
        }
    }
}

Et vous avez terminé. Et vous pouvez maintenant traitez la vue popover comme toute autre vue, c'est-à-dire. ajouter des champs et ce qui ne! Et vous obtenez le contrôleur de contenu en utilisant la méthode popoverPresentationController.presentedViewController dans le UIPopoverPresentationController.

Aussi sur un iPhone, vous devrez écraser

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {

        return UIModalPresentationStyle.none
    } 
46
répondu user1700737 2017-05-06 21:38:53

J'ai trouvé un exemple complet de la façon de faire fonctionner tout cela afin que vous puissiez Toujours afficher un popover peu importe le périphérique / l'orientation https://github.com/frogcjn/AdaptivePopover_iOS8_Swift .

La clé consiste à implémenter UIAdaptivePresentationControllerdelegate

func adaptivePresentationStyleForPresentationController(PC: UIPresentationController!) -> UIModalPresentationStyle {
    // This *forces* a popover to be displayed on the iPhone
    return .None
}

Ensuite, étendez l'exemple ci-dessus (à partir D'Imagine Digital):

nav.popoverPresentationController!.delegate = implOfUIAPCDelegate
28
répondu David Hunt 2014-09-24 20:00:15

Swift 2.0

Eh bien, je me suis entraîné. Un coup d'oeil. Fait un ViewController dans StoryBoard. Associé à la classe PopOverViewController.

import UIKit

class PopOverViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()    
        self.preferredContentSize = CGSizeMake(200, 200)    
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "dismiss:")    
    }    
    func dismiss(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}      

Voir ViewController:

//  ViewController.swift

import UIKit

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate
{
    func showPopover(base: UIView)
    {
        if let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("popover") as? PopOverViewController {    

            let navController = UINavigationController(rootViewController: viewController)
            navController.modalPresentationStyle = .Popover

            if let pctrl = navController.popoverPresentationController {
                pctrl.delegate = self

                pctrl.sourceView = base
                pctrl.sourceRect = base.bounds

                self.presentViewController(navController, animated: true, completion: nil)
            }
        }
    }    
    override func viewDidLoad(){
        super.viewDidLoad()
    }    
    @IBAction func onShow(sender: UIButton)
    {
        self.showPopover(sender)
    }    
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
        return .None
    }
}  

Remarque: la méthode func showPopover (base: UIView) doit être placée avant ViewDidLoad. Espérons que cela aide !

25
répondu A.G 2016-03-07 06:23:17

Dans iOS9 UIPopoverController est amorti. Donc, peut utiliser le code ci-dessous pour la version Objective-C ci-dessus iOS9.x,

- (IBAction)onclickPopover:(id)sender {
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
UIViewController *viewController = [sb instantiateViewControllerWithIdentifier:@"popover"];

viewController.modalPresentationStyle = UIModalPresentationPopover;
viewController.popoverPresentationController.sourceView = self.popOverBtn;
viewController.popoverPresentationController.sourceRect = self.popOverBtn.bounds;
viewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:viewController animated:YES completion:nil]; }
11
répondu Vijay 2016-04-21 08:58:47

Ici, je convertit le Code Swift "Joris416" en Objective-c,

-(void) popoverstart
{
    ViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"PopoverView"];
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:controller];
    nav.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popover = nav.popoverPresentationController;
    controller.preferredContentSize = CGSizeMake(300, 200);
    popover.delegate = self;
    popover.sourceView = self.view;
    popover.sourceRect = CGRectMake(100, 100, 0, 0);
    popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
    [self presentViewController:nav animated:YES completion:nil];
}

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

N'oubliez pas d'AJOUTER
UIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate

7
répondu user2941395 2015-09-07 16:55:21

C'est mieux expliqué sur le iOS8, jour par Jour, le blog

En bref, une fois que vous avez défini modalPresentationStyle de votre UIViewController sur .Popover, vous pouvez obtenir une UIPopoverPresentationClass (une nouvelle classe iOS8) via la propriété popoverPresentationController du contrôleur.

4
répondu Clafou 2014-10-14 11:01:38

J'ai fait une version Objective-C de Imagine Digitals réponse rapide ci-dessus. Je ne pense pas avoir manqué quoi que ce soit car il semble fonctionner sous des tests préliminaires, si vous repérez quelque chose, faites-le moi savoir, et je le mettrai à jour

-(void) presentPopover
{
    YourViewController* popoverContent = [[YourViewController alloc] init]; //this will be a subclass of UIViewController
    UINavigationController* nav =  [[UINavigationController alloc] initWithRootViewController:popoverContent];
    nav.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController* popover = nav.popoverPresentationController;
    popoverContent.preferredContentSize = CGSizeMake(500,600);
    popover.delegate = self;
    popover.sourceRect = CGRectMake(100,100,0,0); //I actually used popover.barButtonItem = self.myBarButton;

    [self presentViewController:nav animated:YES completion:nil];
}
2
répondu narco 2015-05-05 18:07:02

Implémentez UIAdaptivePresentationControllerdelegate dans votre Viewcontroller. Puis ajoutez:

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle{
    return .none
}
2
répondu Nyakiba 2016-11-30 10:41:26

Mes deux cents pour xcode 9.1 / swift 4.

Classe ViewController: UIViewController, UIPopoverPresentationControllerDelegate {

override func viewDidLoad(){
    super.viewDidLoad()


    let when = DispatchTime.now() + 0.5
    DispatchQueue.main.asyncAfter(deadline: when, execute: { () -> Void in
        // to test after 05.secs... :)
        self.showPopover(base: self.view)
    })

}


func showPopover(base: UIView)
{
    if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "popover") as? PopOverViewController {

        let navController = UINavigationController(rootViewController: viewController)
        navController.modalPresentationStyle = .popover

        if let pctrl = navController.popoverPresentationController {
            pctrl.delegate = self

            pctrl.sourceView = base
            pctrl.sourceRect = base.bounds

            self.present(navController, animated: true, completion: nil)
        }
    }
}


@IBAction func onShow(sender: UIButton)
{
    self.showPopover(base: sender)
}

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

Et expérimentez dans:

Func adaptivePresentationStyle...

    return .popover

Ou: retourner .pageSheet.... et ainsi de suite..

1
répondu ingconti 2017-12-14 20:33:37

Swift 3: Dans mon cas, a priori, on sait seulement que le UIViewController sous-jacent est un TextViewController (mon nom pour le UIViewController dont j'ai besoin pour popover), qu'il peut s'agir d'un popOverPresentationController et qu'il contient un NSMutableAttributedString.

Ce sont toutes les informations nécessaires pour construire le popOverPresentationController à la taille correcte en utilisant la taille de la NSMutableAttributedString, puis en définissant la taille de la UIViewController à la taille de la chaîne qui lui est livrée. Je crée un NSMutableAttributedString, définit son contenu en utilisant une méthode appelée " createStats ()".

Veuillez noter que je dois définir la taille de contenu préférée de UIViewController sous-jacente, donc j'utilise: tvc.preferredContentSize pour le définir. Le UIViewController est nommé "tvc". J'utilise tvc.preferredContentSize = CGSizeFromString(chaîne (décrivant: myCreatedAttributedMutableString)).

Mon popOverPresentationController (qui est un UIViewController) a un textView. Donc, dans le storyboard, j'ai défini le textView pour être "attribué". entrez la description de l'image ici

Le textView a une chaîne (appelée "opérations") qui lui est livrée avec le segue. Cette chaîne ("opérations") est le contenu entier à afficher lorsque le popover se produit.

Donc ma solution est d'utiliser ce qui suit dans la préparation (pour segue: ...)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if let tvc = segue.destination as? TextViewController {
        if let ppc = tvc.popoverPresentationController {
            ppc.delegate = self
        }

        let returnStatsStr: NSMutableAttributedString = createStats()

        let myCreatedAttributedMutableString = NSMutableAttributedString.init()

        myCreatedAttributedMutableString.append(returnStatsStr)

        tvc.operations = myCreatedAttributedMutableString
        tvc.preferredContentSize = CGSizeFromString(String(describing: myCreatedAttributedMutableString))

    }

}

Voici comment il apparaît quand il pop.

Entrez la description de l'image ici

-1
répondu user6216481 2017-04-27 14:02:47