ios swift uipopovercontroller ios8 uipopover

Cómo presentar popover correctamente en iOS 8



swift uipopovercontroller (11)

Aquí convierto el código Swift "Joris416" a 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; }

Recuerde AGREGAR
UIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate

Estoy tratando de agregar un UIPopoverView a mi aplicación Swift iOS 8, pero no puedo acceder a la propiedad PopoverContentSize, ya que el popover no se muestra en la forma correcta. mi código:

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 salida:

Cuando estoy haciendo lo mismo a través de UIPopoverPresentationController, todavía no lo hago. este es mi código:

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) }

Obtengo el mismo resultado exacto.

¿Cómo personalizo el tamaño de mi popover? ¡Cualquier ayuda sería muy apreciada!


De acuerdo, un compañero de casa lo miró y lo descubrió:

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) }

Esa es la manera.

Ya no hablas con el popover, hablas con el controlador de vista dentro de él para establecer el tamaño del contenido, llamando a la propiedad preferredContentSize


En iOS9 UIPopoverController se deprecia. Entonces puede usar el siguiente código para la versión Objective-C arriba de 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]; }


En realidad, es mucho más simple que eso. En el guión gráfico, debe hacer que viewcontroller quiera usar como popover y crear una clase viewcontroller para él como de costumbre. Haga una transición como se muestra a continuación desde el objeto que desea abrir el popover, en este caso el UIBarButton llamado "Config".

En el "mother viewcontroller", implementa el UIPopoverPresentationControllerDelegate y el método de delegado:

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

Reemplace el método prepareForSeque esta manera:

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) } } }

Y tu estas listo. Y ahora puede tratar la vista de popover como cualquier otra vista, es decir. agregar campos y qué no! Y puede obtener el controlador de contenido utilizando el método popoverPresentationController.presentedViewController en UIPopoverPresentationController .

También en un iPhone tendría que sobrescribir

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


Encontré un ejemplo completo de cómo hacer que todo esto funcione para que siempre puedas mostrar un popover sin importar el dispositivo / orientación https://github.com/frogcjn/AdaptivePopover_iOS8_Swift .

La clave es implementar UIAdaptivePresentationControllerDelegate

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

A continuación, amplíe el ejemplo anterior (de Imagine Digital):

nav.popoverPresentationController!.delegate = implOfUIAPCDelegate


Esto se explica mejor en el blog de iOS8 Day-by-Day

En resumen, una vez que haya configurado el modalPresentationStyle de su UIViewController en .Popover, puede obtener una UIPopoverPresentationClass (una nueva clase iOS8) a través de la propiedad popoverPresentationController del controlador.


Hice una versión de Objective-C de la respuesta rápida de Imagine Digitals arriba. No creo que me haya perdido nada, ya que parece funcionar en pruebas preliminares, si detecta algo, hágamelo saber y lo actualizaré

-(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]; }


Implemente UIAdaptivePresentationControllerDelegate en su Viewcontroller. Luego añade :

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


mis dos centavos para xcode 9.1 / swift 4.

ViewController de clase: 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 }

y experimentar en:

func adaptivePresentationStyle ...

return .popover

o: return .pageSheet .... y así sucesivamente ..


Swift 2.0

Bueno, funcioné. Echar un vistazo. Hizo ViewController en StoryBoard. Asociado con la clase 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) } }

Ver 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 } }

Nota: El método func showPopover (base: UIView) debe colocarse antes de ViewDidLoad. Espero eso ayude !


Swift 3: En mi caso, a priori, solo hay conocimiento de que el UIViewController subyacente es un TextViewController (mi nombre para el UIViewController necesito popover), que puede ser un PopOverPresentationController y que contiene un NSMutableAttributedString.

Esta es toda la información necesaria para construir popOverPresentationController para que tenga el tamaño correcto utilizando el tamaño de NSMutableAttributedString y luego estableciendo el tamaño del UIViewController al tamaño de la cadena que se le entrega. Creo un NSMutableAttributedString, establezco su contenido usando un método llamado "createStats ()".

Tenga en cuenta que necesito establecer el tamaño de contenido preferido subyacente de UIViewController para que use: tvc.preferredContentSize para configurarlo. El UIViewController se llama "tvc". Yo uso tvc.preferredContentSize = CGSizeFromString (String (describiendo: myCreatedAttributedMutableString)).

Mi popOverPresentationController (que es un UIViewController) tiene un textView. Entonces en el guión gráfico, configuré el textView para ser "Atribuido". enter image description here

El textView tiene una cadena (llamada "operaciones") que se le entrega con el segue. Esta cadena ("operaciones") es todo el contenido que se mostrará cuando se produzca el popover.

Entonces mi solución es usar lo siguiente en la preparación (por 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)) } }

Así es como aparece cuando aparece.

enter image description here