[Résolu] UIImagePickerController sur plusieurs UIImageViews

busterTheobusterTheo Membre
février 2015 modifié dans API UIKit #1

Bonjour,


Je fais simple...


 


Je développe en swift sur Xcode 6.1.1


 


Je dois choisir 5 photos à  partir de l'album avec un UIImagePickerController, à  partir de 5 UIImageViews qui sont dans le storyBoard.


Comment récupérer la référence du UIImageView sur lequel je clique, au sein de la fonction suivante ?



func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {}

Cela, afin d'assigner l'image sélectionnée dans le picker, au bon UIImageView.



Merci d'avance.



busterTheo


Réponses

  • Clique sur le bouton "Modifier" de ton post, puis sur le bouton "Utiliser l'éditeur complet" pour modifier le titre de ton topic.


  • busterTheobusterTheo Membre
    février 2015 modifié #3

    Ah, super. Merci pour ta remarque. Je suis nouveau sur ce forum.


    Et t'aurais pas une idée pour mon pb ?


    J'exagère, hein... Mais bon, j'ai cherché depuis deux jours sur le web, et rien à  ce sujet.


  • Je n'ai jamais utilisé UIImagePickerController, désolé !

  • AliGatorAliGator Membre, Modérateur
    Tel que UIImagePickerController est pensé, ce n'est pas possible.

    En plus ça fait partie des classes qui sont apparues du temps où il n'y avait pas les blocks et que les delegate, donc quand une action était asynchrone comme ici (on a la réponse de savoir "quelle image est choisie" bien plus tard, quand l'utilisateur a sélectionné son image), on a la réponse via une méthode de delegate comme ici... donc un appel d'une méthode complètement autre part dans le code, dans une méthode qui n'est pas liée à  la méthode où on a appelé le UIImagePickerController.

    Ce qui fait qu'au final tu appelles ton UIImagePickerController dans une méthode donnée (méthode dans laquelle tu connais certainement ton UIImageView tapée) et tu as la réponse dans une autre méthode (la méthode de delegate), qui est indépendante et ne connais pas ton UIImageView.




    Une solution Quick & Dirty est de garder la UIImageView tapée dans une @property avant d'afficher ton UIImagePickerController, et d'utiliser cette @property quand la méthode de delegate est appelée.

    Une solution beaucoup plus clean est de wrapper le UIImagePickerController et sa méthode de delegate dans une petite classe qui encapsule toute cette mécanique avec des blocks, plutôt qu'avec des delegate.
  • Merci AliGator pour ta réponse précise. Mais je n'ai pratiquement rien compris (Chui un peu débutant - Mais je maà®trise les delegate, protocole, classe  et autres, quand même).


     


    En gros tu veux dire, que même avec des tags sur les UIImageViews, mis, soit dans le storyboard, soit dans le code, je ne peux pas récupérer le UIImageView sur lequel je clique ? ça craint quand même !


     


    Effectivement, quand tu dis "méthode dans laquelle tu connais certainement ton UIImageView tapée", bien sûr, je l'ai fait avec un seul UIImageView et ça marche impec Logique. C'est la base.


     


    Mais là , j'ai vraiment besoin, dans mon appli, de choisir 5 photos. Cela veut dire que je dois, enchainer un écran par choix de photos... 


     


    Lorsque tu dis "de wrapper le UIImagePickerController et sa méthode de delegate dans une petite classe qui encapsule toute cette mécanique avec des blocks, plutôt qu'avec des delegate", je ne comprend pas trop. Tu entend quoi par "blocks" ? Et, si cela n'est pas trop abuser, heu, t'aurais pas un exemple ? Parce que "et sa méthode de delegate" et "plutôt qu'avec des delegate", cela me confusionne un peu d;-)


     


    En tout cas, encore merci pour le temps que tu as consacré à  mon problème.


     


    Je suis quand même étonné que cela soit si compliqué de picker plusieurs photos dans un même écran.


    Enfin, je dois être encore un peu naà¯f sur les applis.


     


    cordialement


     


    busterTheo


  • AliGatorAliGator Membre, Modérateur
    Je t'invite d'abord à  passer par la case présentation, en allant écrire un message dans le forum "Présentation des Membres".

    Car là  on ne connais pas ton niveau, donc on ne peut pas te répondre efficacement. Manifestement, j'ai préjugé par exemple que tu connaissais les blocks / closures alors que cela ne semble pas être le cas.



    Enfin, ce n'est pas du tout difficile de picker plusieurs photos dans un même écran.
    Ce qui est difficile, c'est que tu n'as qu'un seul et même delegate (ton ViewController) quel que soit le code qui te crée ton picker et le présente. Du coup, quand ta méthode de delegate est appelée, comme c'est le même delegate pour tout le monde, tu n'as pas moyen de différencier de quelle UIImageView ça vient, car c'est le même delegate pour tout le monde.


    La solution que je proposais était d'avoir des delegate différents, et pour faire cela proprement, je proposais de faire un wrapper pour convertir la mécanique de delegate en mécanique de closure, + répandue de nos jours et encore + avec Swift.

    Mais manifestement tu n'en n'es pas encore là , donc c'est sans doute un exercice trop compliqué pour toi. Et du coup la solution Quick & Dirty (de mettre de côté dans une property la UIImageView tapée avant d'afficher le picker, et récupérer cette UIImageView via la propriété dans la méthode de delegate) est beaucoup plus simple à  mettre en place et peut te convenir dans un premier temps.
  • AliGatorAliGator Membre, Modérateur
    Exemple très simple testé à  l'instant et qui marche très bien :
    class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    var lastTappedImageView: UIImageView?

    @IBAction func imageViewTapped(recognizer: UIGestureRecognizer)
    {
    if recognizer.state != .Ended { return }

    self.lastTappedImageView = recognizer.view as? UIImageView

    let picker = UIImagePickerController()
    picker.sourceType = .PhotoLibrary
    picker.delegate = self

    self.presentViewController(picker, animated: true) {}
    }

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
    picker.dismissViewControllerAnimated(true) {}

    self.lastTappedImageView?.image = info[UIImagePickerControllerOriginalImage] as? UIImage
    self.lastTappedImageView = nil
    }

    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
    picker.dismissViewControllerAnimated(true) {}
    self.lastTappedImageView = nil
    }

    }
    Et dans mon Storyboard, j'ai une vue avec 4 UIImageView, sur chaque UIImageView j'ai coché la case UserInteractionEnabled et j'ai mis un TapGestureRecognizer dessus, qui déclenche la même @IBAction pour chacun des 4 recognizers, à  savoir l'action "imageViewTapped()".
  • Rebonjour AliGator,


    je viens de lire tes messages avant d'aller me coucher.


    Tout d'abord, je vais faire comme tu m'as dit, je vais aller écrire un message dans le forum "Présentation des Membres". Demain.


    Ensuite, je t'ai lu en travers, mais promis, demain j'étudie tes explications. En tout cas, ça a l'air top.


    Tu dis vrai pour les blocks / closures. J'ai croisé les closures mais je n'ai pas approfondi.


     


    Juste au passage, je n'ai pas construit avec des UIButton mais comme ça. Je pense que tu comprendras. On a le droit ?


    En gros j'associe le UITapGestureRecognizer aux UIImageViews pour les relier à  la function "choisirImage"



    // Tapper photo
    let taperPhoto: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "choisirImage:")
    taperPhoto.numberOfTapsRequired = 1
    let taperPhoto2: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "choisirImage:")
    taperPhoto2.numberOfTapsRequired = 1
    let taperPhoto3: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "choisirImage:")
    taperPhoto3.numberOfTapsRequired = 1
    let taperPhoto4: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "choisirImage:")
    taperPhoto4.numberOfTapsRequired = 1
    let taperPhoto5: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "choisirImage:")
    taperPhoto5.numberOfTapsRequired = 1

    // Properties 5 ImageViews
    frontalPatientImageView.addGestureRecognizer(taperPhoto)
    frontalPatientImageView.userInteractionEnabled = true

    BpnmbfPatientImageView.addGestureRecognizer(taperPhoto2)
    BpnmbfPatientImageView.userInteractionEnabled = true

    CfnmsPatientImageView.addGestureRecognizer(taperPhoto3)
    CfnmsPatientImageView.userInteractionEnabled = true

    DpnmsPatientImageView.addGestureRecognizer(taperPhoto4)
    DpnmsPatientImageView.userInteractionEnabled = true

    EaiETsPatientImageView.addGestureRecognizer(taperPhoto5)
    EaiETsPatientImageView.userInteractionEnabled = true

    Puis la function choisirImage



    func choisirImage(recognizer: UITapGestureRecognizer) {
    let picker = MyImagePickerController()
    picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
    picker.mediaTypes = UIImagePickerController.availableMediaTypesForSourceType(picker.sourceType)!
    picker.delegate = self
    picker.allowsEditing = false

    self.view.window?.rootViewController?.presentViewController(picker, animated: true, completion: nil)
    }

    Et la méthode du picker pour l'instant uniquement basée sur une seule imageView (la première - frontalPatientImageView)



    / MARK: - UIImagePickerControllerDelegate Methods

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
    let imagePickee: UIImage = info[UIImagePickerControllerOriginalImage] as UIImage

    //Scale photo
    let screenSize: CGSize = UIScreen.mainScreen().bounds.size
    var newImageScaled: UIImage = scaledImageWithImage(imagePickee, size: CGSize(width: screenSize.width, height: screenSize.height))

    //L'image sélectionnée va dans le UIImageView
    self.frontalPatientImageView.image = newImageScaled

    //Adresse répertoire photos
    let paths: NSArray = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
    let documentsDir: NSString = paths.objectAtIndex(0) as NSString

    //On fabrique le nom de la photo
    var dateFormat = NSDateFormatter()
    dateFormat.dateFormat = "yyyy-MM-dd-HH-mm-ss"
    let now: NSDate = NSDate(timeIntervalSinceNow: 0)
    let theDate: NSString = dateFormat.stringFromDate(now)
    self.frontalPatientFullURL = NSString(format: "Frontal\(nomTextField.text)-%@.png", theDate)

    //On fabrique le chemin total
    let pathFull: NSString = documentsDir.stringByAppendingString(self.frontalPatientFullURL!)

    //On fabrique l'image
    let pngFullData: NSData = UIImagePNGRepresentation(newImageScaled)
    pngFullData.writeToFile(pathFull, atomically: true)

    picker.dismissViewControllerAnimated(true, completion: nil)
    }

    Je ne te met pas la function scaledImageWithImage pour ne pas te surcharger, mais tu imagines...


     


    Concernant la navigation, je suis dans un container avec une sideNav. C'est un peu compliqué à  expliquer. Dis moi si tu préfères que je te joignes le projet total. Ce serait certainement plus simple. Mais je ne veux pas non plus t'accaparer. Déjà , je pense que je devrais creuser ton idée de "d'avoir des delegate différents".


     


    En même temps, je crois aussi que ton idée de se servir d'un 



    @IBAction func imageViewTapped(recognizer: UIGestureRecognizer)

    me semble le plus simple, bien que je doive reconstruire tout cela.


     


    IBAction ou plusieurs delegate ? That is the question d;-)


     


     


    En tout cas merci encore. Tes explications me rassurent.


    Cordialement.


     


    busterTheo

  • AliGatorAliGator Membre, Modérateur
    De ce que je vois tu as déjà  tout ce qu'il faut pour coller à  ce que j'ai fait : tu as mis des GestureRecognizer sur tes UIImageView comme j'ai mis dans mon exemple de code (moi non plus je ne suis pas passé par des UIButton non m'as mais ai bien fait comme toi, donc) et tous tes recognizers pointent vers une même action " que toi tu as appelé choisirImage et que moi j'ai appelé imageViewTapped, mais à  part le nom c'est pareil.


    Le seul truc qui manque donc dans ton code de ta méthode choisirImage c'est de stocker la recognizer.view dans une propriété de ton ViewController pour pouvoir la récupérer plus tard dans ta méthode de delegate. C'est tout. T'étais pas loin finalement.



    ---

    (bon et quand tu utilises un GestureRecognizer penses à  n'exécuter ton code que si "recognizer.state == .Ended" car l'action associée à  un GestureRecognizer est exécutée pour tous ses états intermédiaires aussi alors que toi tu ne veux afficher ton picker que quand la gesture de tap est reconnue " mais bon ce détail n'a rien à  voir avec ta question sur les UIImageView et les UIImagePickerController, c'est juste une précision sur les GestureRecognizer au passage)
  • Bonjour AliGator,


    merci pour tes encouragements.


    J'ai mieux compris le problème, et après quelques suées, je m'en suis sorti grâce à  ton code et à  tes explications. C'est génial.


    Je vais donc mettre le sujet comme résolu (faut que je trouve où c'est...), et faire mes présentations dans forum "Présentation des Membres".


     


    Encore merci. Je peux,maintenant que ma structure de base est prête, me consacrer à  la suite (zooms images, UIControls, etc), et là  c'est pas gagné. Mais j'ai quand même fait pas mal de p'tits codes grâce à  des tutos. Et je devrais m'en sortir. Je viendrais sur le forum  si je galère.


     


    Cordialement.


     


    busterTheo

  • AliGatorAliGator Membre, Modérateur

    Je vais donc mettre le sujet comme résolu (faut que je trouve où c'est...), et faire mes présentations dans forum "Présentation des Membres".

    Il n'y a pas de bouton ou de truc tout fait prévu pour ça dans le forum.

    Du coup c'est plutôt juste une convention que d'éditer le titre du sujet pour le modifier et rajouter à  la main le "[Résolu]" devant le titre.

    Pour éditer le titre du sujet, il suffit d'éditer le tout premier message de ce fil de discussion (bouton "Modifier" en bas du premier post de ce sujet), en prenant soin de passer ensuite en mode "Utiliser l'Editeur Complet" (pour pouvoir modifier non pas que le texte du post mais aussi donc son titre).
  • AliGatorAliGator Membre, Modérateur
    Et sinon juste pour info, la solution (de stocker temporairement dans une propriété l'UIImageView pour pouvoir la relire dans ta méthode de delegate) fonctionne, mais ce n'est pas ce qu'il y a de plus clean en terme d'architecture logicielle.

    Ca veut dire que tu as une propriété sur tout ton ViewController alors qu'elle ne te sert et n'a de sens que quand tu es dans une certaine phase (entre le moment où le picker est affiché et celui où l'utilisateur a choisi une image), et que dans tous les autres cas cette propriété est là  pour rien. C'est n'est pas terrible en terme de bonne architecture de code.

    Bon pour ton cas ça passe parce que tu veux avancer, et que tu es débutant et va sûrement t'en contenter. Mais si on veut faire les choses bien il y a des solutions plus propres en terme de bonnes pratiques qui existent (mais qui nécessitent d'avoir un meilleur niveau, donc je ne vais pas m'étendre dessus). Parmi les solutions qu'on peut imaginer :
    - associer ton objet UIImageView (avec les associatedObjects du runtime ObjC) à  ton UIImagePickerController au moment où tu crées ce dernier. Comme ensuite dans ta méthode de delegate tu as accès à  ce picker, tu peux alors en réextraire l'UIImageView associée pour la récupérer
    - Créer un petit wrappeur qui va encapsuler toute la logique de picker + delegate dans un objet dédié, et permettre de fournir une closure à  appeler quand la méthode de delegate est déclenchée. Ainsi grace à  ce wrapper, tu auras une API qui utilise une closure et non plus des delegate, et tu pourras fournir directement au même endroit le code qui crée le picker et le code à  exécuter quand l'utilisateur a choisi son image (plutôt que d'avoir le début du code dans ton IBAction et la fin dans ta méthode de delegate). Conséquence, tu auras accès aux mêmes variables locales, dont ta UIImageView que tu connais encore quand tu restes dans le code de ton IBAction.
    - Utiliser des concepts de plus haut niveau, comme PromiseKit & co... qui finalement vu leurs concepts proposent déjà  ce wrapper qui expose un completionBlock / une closure plutôt que de passer par les delegate


    Bon, c'est peut-être encore un peu tôt si tu viens de t'y remettre pour te parler dès à  présent de ces concepts haut niveau, mais c'est + pour que tu saches que sa existe et qu'il y a plus propre comme solution, quitte à  ce que tu y reviennes plus tard quand tu seras + à  l'aise.
  • Bon, j'ai mis le résolu. Et au fait, je me suis présenté.


    Concernant tes remarques, j'achète, bien que je n'y comprenne pas grand chose. Je vais creuser tout ça. De toute les façons je dois faire un code hyper propre et conforme, car je dois livrer cette appli en septembre et il faut que Apple me la valide. Sans quoi, je suis dans la mouise.


     


    Pour l'instant je crée de nombreux fichiers pour tester tous les trucs que je dois faire (zooms, controls, etc). Et là , je suis content d'avoir ce squelette qui fonctionne (en plus avec du coredata selon les codes du nouveau doc masterDetail d'Apple pour sauvegarder les données) pour y ajouter les nouvelles fonctionnalités sus-nommées.


     


    En tout cas, merci pour tes recommandations sur ces concepts de haut niveau.


     


    Je fonce sur google pour voir ce que c'est que ce truc "associatedObjects du runtime ObjC".


    ça fait peur, ça sent le objC. Bon, on verra bien. d;-)


     


    busterTheo


  • AliGatorAliGator Membre, Modérateur
    Honnêtement le coup des associatedObjects n'est pas la solution la plus propre qui soit et c'est même un peu de la bidouille (limite + que ta solution actuelle de propriété qui ne sert que pour le temps du picker)


    La solution la plus propre reste l'encapsulation de picker + son délégate dans un wrapper qui expose une closure pour avoir une API plus propre. Je suis même étonné qu'Apple n'ait pas fait évoluer L'API de UIImagePickerController de la s'utilise historique utilisant un délégate vers une API utilisant un completionBlock / une closure. Ils l'ont déjà  fait pour d'autres classes (je pense à  NSURLConnection par exemple) ils auraient pu le faire pour le picker aussi...
  • AliGatorAliGator Membre, Modérateur
    février 2015 modifié #16
    Voilà  ma solution avec une classe (que j'ai appelé ImagePicker) qui encapsule un UIImagePicker et son delegate.
  • busterTheobusterTheo Membre
    février 2015 modifié #17

    Bonjour Alligator,


    je ne sais pas si c'est correct de te répondre sur ce post, vu qu'il est marqué comme résolu, mais je me lance quand même.

     

    Déjà , c'est vraiment sympa de ta part de me consacrer tout ce temps.

    J'ai étudié ton code et tes explications en profondeur, et je suis séduit par ce principe qui regroupe tout le code au même endroit. Il y a plusieurs choses que je ne comprend pas (comme par ex le “{ imageInfo in”), cela est du à  mes lacunes en POO, et je ne t'ennuierai pas avec cela, en tout cas pour l'instant. Je fais mes recherches sur le web pour y remédier.

     

    Je suis juste un peu découragé, car j'ai mis au moins un mois à  construire mes propres delegate/protocol de mes fichiers, et c'est vrai que c'est pénible d'avoir du code un peu partout. Mais bon, pas le choix, faut évoluer.

     

    Par contre, j'ai noté que l'on devait présenter le UIImagePickerController sur iPad avec la méthode



    popover.presentPopoverFromRect(rect, inView: view, permittedArrowDirections: arrowDirections, animated: true)

    Alors j'ai essayé de l'utiliser dans mon projet, plutôt que la méthode



    presentViewController(picker, animated: true, completion: nil)

    que j'utilisais. J'avais déjà  croisé cette info, mais comme je travaille avec une sideNav, et donc la partie de droite est modifiée par des



    pushViewController(nouveauPatientViewController, animated: true)

    j'avais ce message d'erreur, bien que le projet se lance bien



    Presenting view controllers on detached view controllers is discouraged

    J'étais donc resté sur ma première version, avec l'astuce (self.view.window?.rootViewController?) trouvée sur le web



    self.view.window?.rootViewController?.presentViewController(picker, animated: true, completion: nil)

    Et là , lorsque je refait le popover.presentPopoverFromRect(), j'ai à  nouveau l'erreur, et je ne parviens pas à  l'éviter.

     

    Aurais tu une astuce ?

     

     


    Au passage, dans ton projet, j'ai du modifier dans viewController.swift



    picker.presentPopover(fromRect: imageView.frame, inView: imageView.superview!)

    par



    picker.presentPopover(fromRect: imageView.frame, inView: imageView.superview!, arrowDirections: .Any)

    et supprimer les “!” dans ImagePicker.swift, dans les “as! String” du “init(mediaInfo: [NSObject:AnyObject]) {}”

     

     

    pour éviter les “warnings”. Je crois que c'est parce que je suis en xCode Version 6.1.1 (6A2008a).

     


    Cela m'arrive souvent lorsque je download des projets de tutos du web.

     

    Je te met un lien sur une vidéo de mon projet. Ce sera plus simple pour comprendre...




     


    En gros, on observe la sideNav, les push, l'enregistrement et l'update.


     


    Voilà . Pour l'instant je ne pousse pas trop sur ces sujets, car j'ai beaucoup à  faire encore.


     


    Encore merci.


     


    busterThéo


  • AliGatorAliGator Membre, Modérateur
    Oui mon projet démo a été écrit avec Xcode 6.3, qui supporte Swift 1.2. Alors que Xcode 6.1 en est encore à  Swift 1.1

    Il y a eu pas mal d'améliorations dans Swift 1.2, en particulier l'apparition de l'opérateur "as!".
    - Avant dans Swift 1.0 et Swift 1.1 on n'avait que "as" et "as?", et l'opérateur "as" était utilisé à  la fois pour les cast toujours possibles (comme quand tu castes un objet vers sa classe parente : par définition un objet Mammifère est forcément aussi un objet Animal donc le cast vers Animal marchera toujours) et les cast qui pouvait rater (à  l'inverse un Animal n'est pas toujours un Mammifère donc un cast de Animal vers Mammifère peut échouer)
    - Avec Swift 1.2 le nouvel opérateur "as!" permet de faire la distinction entre les 2 et de rendre les choses plus claires.
  • AliGatorAliGator Membre, Modérateur
    Quant au "{ imageInfo in ... }" c'est la syntaxe en Swift pour les paramètre dans une closure.

    Quand j'appelle ma closure dans la méthode de delegate, avec self.completion(info), je passe le contenu de la variable "info" à  ma closure "completion", comme quand tu passes un paramètre à  une fonction (en Swift une closure et une fonction sont interchangeables, d'ailleurs).

    Et du coup de l'autre côté quand tu fournis le code de ta closure à  exécuter quand l'utilisateur a choisi l'image, il faut bien récupérer ce paramètre pour en faire quelque chose d'utile (en l'occurence en extraire la originalImage pour l'affecter à  l'imageView). C'est à  ça que sert le "{ imageInfo in ... }"


    // Syntaxe générale d'une closure :
    { (<les paramètres>) in <le code> }

    // Exemple :
    { (x,y) in println("x vaut \(x) et y vaut \(y).") }

    // Quand il n'y a qu'un seul paramètre, on peut omettre les parenthèses :
    { x in println("x vaut \(x)") }

    // Et quand il n'y a pas de paramètre du tout, on peut directement mettre le code sans le "in" :
    { println("Pas de paramètre") }
  • ah je ne savais pas qu'il y avait Xcode 6.3 et Swift 1.2.


    Je suis la tête dans le code 24/24


    J'ai peur de le télécharger... Je vais attendre un peu. Merci pour l'info


  • AliGatorAliGator Membre, Modérateur
    février 2015 modifié #21
    Xcode 6.3 est encore en Beta. Du coup je ne suis pas sûr qu'il soit automatiquement proposé comme une mise à  jour via l'AppStore par exemple. Mais il est disponible au téléchargement sur developer.apple.com si tu ne veux pas attendre la fin de la phase Beta.


    En général, surtout pour les débutants, je conseille d'attendre la version officielle plutôt que de tester la Beta. Mais dans ce cas je ferais bien une exception et te conseillerais bien de la télécharger et l'utiliser, car parmi toutes les nouveautés apportées par cette version, il y a en particulier une meilleure stabilité du compilateur Swift et aussi de meilleurs messages d'erreur (plus explicites ou qui sortent la bonne erreur), là  où jusqu'à  présent Xcode était connu pour ne pas être très clair sur certaines erreurs en Swift (genre te dire qu'il ne connaissait pas une méthode alors qu'en fait elle existait mais avait un paramètre qui n'avait pas exactement le bon type, etc)
  • Ah d'acord, mais je vais quand même attendre, vu mon niveau. Sans quoi t'as pas une idée pour ma demande d'astuce sur l'erreur “Presenting view controllers on detached view controllers is discouraged” expliquée dans mon précédent post ?


    Cordialement.


     


    busterTheo


  • AliGatorAliGator Membre, Modérateur
    Non je l'ai déjà  vue dans le cas d'un presentModal quand tu essayes de présenter sur un ViewController qui n'est pas plein écran. Mais dans un popover j'ai jamais eu ce cas.
  • DrakenDraken Membre
    février 2015 modifié #24


    Xcode 6.3 est encore en Beta. Du coup je ne suis pas sûr qu'il soit automatiquement proposé comme une mise à  jour via l'AppStore par exemple.




    Effectivement, la bêta n'existe pas sur l'AppStore.


  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2015 modifié #25
    Non, il faut la télécharger du Developer Center
  • Merci pour les infos


Connectez-vous ou Inscrivez-vous pour répondre.