web-dev-qa-db-fra.com

Comment présenter Popover correctement dans iOS 8

J'essaie d'ajouter un UIPopoverView à mon Swift application iOS 8, mais je ne parviens pas à accéder à la propriété PopoverContentSize, le popover n'apparaissant pas sous 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)
}

sortie:

enter image description here

Lorsque je fais la même chose avec 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)

}

Je reçois exactement la même sortie.

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

114
Joris416

Ok, un colocataire a jeté un coup d'oeil 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 comme ça.

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

144
Joris416

En fait, c'est beaucoup plus simple que cela. Dans le storyboard, vous devez définir le contrôleur de vue que vous souhaitez utiliser et créer une classe viewcontroller comme d'habitude. Comme indiqué ci-dessous, séparez l'objet que vous voulez ouvrir, dans ce cas, le UIBarButton nommé "Config".

enter image description here

Dans le "contrôleur de vue mère", implémentez la méthode UIPopoverPresentationControllerDelegate et la méthode déléguée:

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 tu as fini. Et vous pouvez maintenant traiter la vue popover comme n'importe quelle autre vue, c.-à-d. ajouter des champs et quoi pas! Et vous obtenez le contrôleur de contenu en utilisant la méthode popoverPresentationController.presentedViewController dans la méthode UIPopoverPresentationController.

Aussi sur un iPhone, vous devrez écraser

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

        return UIModalPresentationStyle.none
    } 
50
user1700737

J'ai trouvé un exemple complet de la procédure à suivre pour que tout cela fonctionne et que vous puissiez toujours afficher un popover quel que soit le périphérique/l'orientation https : //github.com/frogcjn/AdaptivePopover_iOS8_Swift .

La clé est d'implémenter UIAdaptivePresentationControllerDelegate

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

Puis développez l'exemple ci-dessus (à partir d'Imagine Digital):

nav.popoverPresentationController!.delegate = implOfUIAPCDelegate
28
David Hunt

Swift 2.

Eh bien j'ai travaillé. Regarde. Fabriqué 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. J'espère que ça aide !

25
A.G

Dans iOS9, UIPopoverController est amorti. Alors 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]; }
14
Vijay

Ici, je convertis "Joris416" Swift Code 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
user2941395

Ceci est mieux expliqué sur le blog iOS8 au jour le jour

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
Clafou

mes deux cents pour xcode 9.1/Swift 4.

class 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érimenter dans:

func adaptivePresentationStyle ...

    return .popover

ou: retourne .pageSheet .... et ainsi de suite ..

3
ingconti

J'ai créé une version Objective-C d'Imagine Digitals Swift ci-dessus. Je ne pense pas avoir manqué quoi que ce soit car il semble fonctionner sous des tests préliminaires, si vous remarquez 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
narco

Implémentez UIAdaptivePresentationControllerDelegate dans votre Viewcontroller. Puis ajouter :

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

Vous trouverez ci-dessous un guide assez complet sur la configuration et la présentation des popovers. https://www.appcoda.com/presentation-controllers-tutorial/

En résumé, une implémentation viable (avec quelques mises à jour de la syntaxe d’article originale pour Swift 4.2 ), qui serait ensuite appelée d’ailleurs, ressemblerait beaucoup à la Suivant:

func showPopover(ofViewController popoverViewController: UIViewController, originView: UIView) {
    popoverViewController.modalPresentationStyle = UIModalPresentationStyle.popover
    if let popoverController = popoverViewController.popoverPresentationController {
        popoverController.delegate = self
        popoverController.sourceView = originView
        popoverController.sourceRect = originView.bounds
        popoverController.permittedArrowDirections = UIPopoverArrowDirection.any
    }
    self.present(popoverViewController, animated: true)
}

Une bonne partie de cela était déjà couverte dans la réponse de @mmc, mais l'article aide à expliquer certains des éléments de code utilisés et à montrer comment il pourrait être développé.

Il fournit également de nombreux détails supplémentaires sur l'utilisation de la délégation pour gérer le style de présentation pour iPhone par rapport à iPad, et pour permettre le renvoi du popover s'il est affiché en plein écran. Encore une fois, mis à jour pour Swift 4.2 :

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

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
    if traitCollection.horizontalSizeClass == .compact {
        return UIModalPresentationStyle.none
        //return UIModalPresentationStyle.fullScreen
    }
    //return UIModalPresentationStyle.fullScreen
    return UIModalPresentationStyle.none
}

func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
    switch style {
    case .fullScreen:
        let navigationController = UINavigationController(rootViewController: controller.presentedViewController)
        let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: #selector(doneWithPopover))
        navigationController.topViewController?.navigationItem.rightBarButtonItem = doneButton
        return navigationController
    default:
        return controller.presentedViewController
    }
}

// As of Swift 4, functions used in selectors must be declared as @objc
@objc private func doneWithPopover() {
    self.dismiss(animated: true, completion: nil)
}

J'espère que cela t'aides.

1
TheNeil

Pour ceux qui veulent étudier!

J'ai créé un projet Open Source pour ceux qui souhaitent étudier et utiliser la vue Popover à des fins diverses. Vous pouvez trouver le projet ici. https://github.com/tryWabbit/KTListPopup

KTListNewResize

0
dreamBegin