Comment implémenter un Popover en Swift 2.0
Joanna Carter
Membre, Modérateur
Après plusieurs tentatives, je vous présente ce que j'espère d'être le plus "Swifteuse" d'implémentations pour gérer un popover selon la dernière version du compilateur. Si vous avez les critiques, n'hésitez pas à répondre
public class PopoverViewController : UIViewController
{
public typealias FonctionDeFermeture = (enregistrer: Bool) -> ()
public var fonctionDeFermeture: FonctionDeFermeture? = nil
override public var modalPresentationStyle: UIModalPresentationStyle
{
get
{
return .Popover
}
set(newStyle)
{
super.modalPresentationStyle = newStyle
}
}
override public var preferredContentSize: CGSize
{
get
{
return CGSize(width: 250.0, height: 250.0)
}
set(newSize)
{
super.preferredContentSize = newSize
}
}
@IBAction func enregistrer()
{
fonctionDeFermeture?(enregistrer: true)
}
@IBAction func annuler()
{
fonctionDeFermeture?(enregistrer: false)
}
}
class ViewController: UIViewController
{
@IBAction func tapLigneSorireButton(sender: UIButton)
{
guard let popoverViewController: PopoverViewController = PopoverViewController(nibName: "PopoverView", bundle: nil) else
{
// quitte en cas d'échec de création de contrôleur de popover
return
}
// utilise closure pour signaler quand le popover se ferme
popoverViewController.fonctionDeFermeture = {//[ capture list ] ( params )
[unowned self, weak popoverViewController] (enregistrer) in
if enregistrer
{
self.enregistrerChangementsDePopover(popoverViewController!)
}
else
{
self.annullerChangementsDePopover(popoverViewController!)
}
self.dismissViewControllerAnimated(true, completion: nil)
}
guard let popoverController = popoverViewController.presentationController as! UIPopoverPresentationController? else
{
// quitte en cas d'échec de création de contrôleur de présentation
return
}
popoverController.sourceRect = sender.frame
popoverController.sourceView = self.view
popoverController.delegate = self
presentViewController(popoverViewController, animated: true, completion: nil)
}
func enregistrerChangementsDePopover(popoverViewController: PopoverViewController)
{
}
func annullerChangementsDePopover(popoverViewController: PopoverViewController)
{
}
}
extension ViewController : UIPopoverPresentationControllerDelegate
{
func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController)
{
annullerChangementsDePopover(popoverPresentationController.presentedViewController as! PopoverViewController)
}
}
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Mais que notre anglaise de service écrive des noms de fonctions et méthodes en français, genre "fonctionDeFermeture", ça par contre je m'y attendais pas
Ils sont super bizarres tes get et set...
Ca veut dire que si je fais par exemple "monPopoverViewController. preferredContentSize = CGSize(width: 150.0, height: 400.0)" et qu'en suite je fais "let sz = monPopoverViewController.preferredContentSize"... il ne vaudra pas 150x400, alors que je viens pourtant de changer sa valeur !! Très perturbant quand même, ça fait pas naturel, tu as un setter qui semble changer la valeur mais le get renvoie en vrai toujours la même chose quelle que soit la valeur que tu aurais pu set avant?!
à‰tant toujours prête à apprendre, c'est préférable d'écrire le code tout en anglais, voir américain ? ::)
Et puis les conventions de nommage Apple (comme par exemple les noms des méthodes d'un protocole) se basent sur l'anglais ("fooController:didUpdateItem:atIndex:"), donc essayer de les retranscrire en français ("fooController:aMisAJourElement:aLIndex:") a beaucoup moins de sens je trouve.
Du coup je trouve quand même bien plus uniforme d'écrire mon code (et donc nommes mes méthodes et variables etc) en anglais, pour garder une cohérence avec les APIs existantes des frameworks Apple, une cohérence avec les mots clés du langage, et avec les conventions de nommage.
Bon, dès maintenant, j'écrirai les messages en français mais le code en anglais
En Objective-C, j'ai, depuis longtemps, rédigé les Popovers comme ça, en redéfinissant les méthodes getter. C'est seulement de l'arrivée de Swift qu'il faut redéfinir, en plus, les setters.
Il s'agit l'encapsulation. Ce que je voulais faire, c'est d'éviter avoir répéter le même code chaque fois que je veuille présenter le même popover. Si je voulais modifier la taille d'un popover selon sa source, je ne redéfinirais pas la méthode.
N'oubliant pas que la propriété s'appelle "preferred"ContentSize et, de ce que j'ai pu déterminer, on ne la "set" souvent. À priori, la propriété est la, surtout, pour répondre aux demandes du contrôleur de présentation.
Si tu bossais en équipe, il vaudrait mieux mettre un petit assert, NSAssert ou l'équivalent en swift dans tes setters.
ou même juste un NSLog.
De façon générale je préfère en anglais aussi parce que ça permet d'écrire sans caractères diacritiques qui sont souvent sources de problèmes. Mêmes s'ils sont de plus en plus supportés dans les nouveaux langages de programmation, on se ramasse toujours des problèmes d'encodage à un moment ou à un autre.
Pourquoi ne pas, plutôt, fournir une valeur par défaut ? Par exemple setter cette valeur dans le init de ta classe? Comme ça comme en pratique vu que toi tu ne vas jamais appeler le setter pour modifier cette valeur, elle aura déjà la bonne valeur grâce à l'init, mais si un jour tu decides quand même pour un de tes PopOver de la modifier, bah ça changera quand même. En gros, faire un VRAI setter et getter, mais fournir une valeur par défaut à la propriété. C'est bien plus propre que d'avoir un truc pas consistent entre le set et le get