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:
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é!
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
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".
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
}
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
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 !
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]; }
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'AJOUTERUIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate
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.
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];
}
Implémentez UIAdaptivePresentationControllerdelegate dans votre Viewcontroller. Puis ajoutez:
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle{
return .none
}
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..
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.