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