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.