Comment implémenter un Popover en Swift 2.0

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

Mots clés:

Réponses

  • AliGatorAliGator Membre, Modérateur
    Alors ça c'est très fort : que certains développeurs français qui ne sont pas du tout à  l'aise avec l'anglais écrivent encore du code en français (alors que comme les mots clés du langage sont en anglais, ça fait souvent du franglais bizarre), je veux bien car ceux-là  ne parlent pas du tout anglais et donc en attendant de se perfectionner dans la langue ils écrivent en français...

    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 :D
  • AliGatorAliGator Membre, Modérateur


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


    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?!
  • Joanna CarterJoanna Carter Membre, Modérateur


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




    à‰tant toujours prête à  apprendre, c'est préférable d'écrire le code tout en anglais, voir américain ?  ::)  :o

  • AliGatorAliGator Membre, Modérateur
    Bah, c'est une question de préférences, mais franchement moi quand je vois du code écrit en français, bah en fait systématiquement c'est forcément du "franglais" finalement, car tu mélanges tes termes français avec des mots clés du langage qui eux sont en anglais.

    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.
  • Joanna CarterJoanna Carter Membre, Modérateur
    août 2015 modifié #6

    Bon, dès maintenant, j'écrirai les messages en français mais le code en anglais 


     




    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?!




     


    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.



  • 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.




     


    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.

  • AliGatorAliGator Membre, Modérateur

    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.

    Mais cela n'empêche pas que du coup c'est totalement incohérent car on peut donner une valeur à  cette propriété et quand on redemande la valeur qu'on a mis elle n'a en fait pas changée...

    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 ;)
Connectez-vous ou Inscrivez-vous pour répondre.