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.
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).
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
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];
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.
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
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
}
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;
}