[SWIFT] Selection d'une image dans une cellule (tableview)

InsouInsou Membre
21 août modifié dans Dev. iOS, watchOS, tvOS #1

Salut tout le monde,

J'ai un soucis qui me fait tourner en rond, j'ai une tableView avec des cellules, chaque cellule comporte un label et une image..
J'aimerai que lorsqu'on clic sur la cellule, on puisse choisir une image dans la galerie et qu'elle remplace l'image présente dans la cellule.

J'ai essayé plusieurs bout de code trouvé sur stackoverflow mais impossible de faire fonctionner quoique ce soit..

Voici mon code :

class ExempleDefisViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableViewExemple: UITableView!
var tabExemple: [JSON] = []
var TabInfosTextfield : [String:String] = [:] // pour recevoir les infos de l'autre vue, exemple : ["nombreDePhotos":"2","nombreDeVideos":"1"]

override func viewDidLoad() {
    super.viewDidLoad()

    if let maTableView = self.tableViewExemple {
        maTableView.dataSource = self
        maTableView.delegate = self
        maTableView.rowHeight = 100 // hauteur des lignes
    }

    if let defis_id = Int(TabInfosTextfield["nombreDePhotos"]!){
        // Ajoute les photos
        if let nbPhotos = Int(TabInfosTextfield["nombreDePhotos"]!){
            if(nbPhotos > 0){
                for i in 1...nbPhotos{
                    tabExemple.append(JSON(["id":i, "type": "photo"]))
                }
            }
        }
        // Ajoute les vidéos
        if let nbVideos = Int(TabInfosTextfield["nombreDeVideos"]!){
            if(nbVideos > 0){
                for i in 1...nbVideos{
                    tabExemple.append(JSON(["id":i, "type": "video"]))
                }
            }
        }
    }
}

// Nombre de ligne
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return tabExemple.count
}

// Pour chaque cellule
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let exemple = tabExemple[indexPath.row]

    let uneCellule = tableView.dequeueReusableCell(withIdentifier: "celluleExemple") as! exempleUpload
    uneCellule.imageCelluleExemple.image = UIImage(named: "upload")

    if(exemple["type"].stringValue == "photo"){
        uneCellule.labelCelluleExemple.text = "Sélectionne une photo comme exemple.."
    }
    else{
        uneCellule.labelCelluleExemple.text = "Sélectionne une vidéo comme exemple.."
    }

    return uneCellule
}

// Lorsqu'on clic sur la cellule
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let exemple = tabExemple[indexPath.row]
    print(exemple)
}

}

// pour la tableDefis, classe pour la cellule custom
class exempleUpload: UITableViewCell {

    @IBOutlet weak var imageCelluleExemple: UIImageView!
    @IBOutlet weak var labelCelluleExemple: UILabel!
    @IBOutlet weak var viewCelluleExemple: UIView!

}

Comment je peux faire pour ajouter la sélection d'une nouvelle image lorsqu'on clic sur la cellule ?

Réponses

  • LarmeLarme Membre
    21 août modifié #2

    J'ai essayé plusieurs bout de code trouvé sur stackoverflow mais impossible de faire fonctionner quoique ce soit..

    Cela ne nous aide pas vraiment. On ne sait pas ce que tu as fais/lu et pourquoi cela ne marchait pas.

    Décomposes plutôt et dis-nous où jusqu'où tu es allé réellement.

    Étape par étape :
    Est-ce que la sélection d'une cellule fonctionne ?
    Est-ce que tu arrives à ouvrir le galerie ? As-tu demandé les autorisations au préalable ?
    Est-ce que tu sais récupérer l'image sélectionnée depuis la galerie ?
    Est-ce que tu sais dire que c'est cette image qui a été sélectionnée et l'utiliser dans ta tableView ?

  • InsouInsou Membre

    Alors,
    Oui, la sélection d'une cellule fonctionne.
    Non, je n'arrive pas à ouvrir la galerie, c'est peut-être au niveau des permissions en effet..
    J'ai rajouté la clé dans le info.plist
    ça n'a rien changé, est-ce-qu'il y a d'autre chose à faire ?

    J'ai re-tester l'exemple de stackoverflow (https://stackoverflow.com/questions/34101524/how-to-run-imagepicker-in-tableviewcell), celui qui ajoute un protocole..

    Voici mon code, je suis pas sûr de tout bien avoir mis au bon endroit :

    protocol ImagePickerDelegate {
        func pickImage()
    }
    
    class ExempleViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, ImagePickerDelegate  {
    
    
    @IBOutlet weak var tableExemple: UITableView!
    var tabExemple: [JSON] = []
    var TabInfosTextfield : [String:String] = [:]
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        if let maTableView = self.tableExemple {
            maTableView.dataSource = self
            maTableView.delegate = self
            maTableView.rowHeight = 100 // hauteur des lignes
        }
    
    
        if let defis_id = Int(TabInfosTextfield["nombreDePhotos"]!){
            // Ajoute les photos
            if let nbPhotos = Int(TabInfosTextfield["nombreDePhotos"]!){
                if(nbPhotos > 0){
                    for i in 1...nbPhotos{
                        tabExemple.append(JSON(["id":i, "type": "photo"]))
                    }
                }
            }
            // Ajoute les vidéos
            if let nbVideos = Int(TabInfosTextfield["nombreDeVideos"]!){
                if(nbVideos > 0){
                    for i in 1...nbVideos{
                        tabExemple.append(JSON(["id":i, "type": "video"]))
                    }
                }
            }
        }
    }
    
    // Nombre de ligne
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tabExemple.count
    }
    
    // Pour chaque cellule
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let exemple = tabExemple[indexPath.row]
    
        let uneCellule = tableView.dequeueReusableCell(withIdentifier: "cellExemple") as! exempleCellUpload
        uneCellule.imageExemple.image = UIImage(named: "upload")
    
        if(exemple["type"].stringValue == "photo"){
            uneCellule.labelExemple.text = "Sélectionne une photo comme exemple.."
        }
        else{
            uneCellule.labelExemple.text = "Sélectionne une vidéo comme exemple.."
        }
    
        uneCellule.delegate = self // image picker
    
        return uneCellule
    }
    
    // Lorsqu'on clic sur la cellule
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let exemple = tabExemple[indexPath.row]
        print(exemple)
    }
    
    func pickImage() {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
        imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
        imagePicker.allowsEditing = false
        self.present(imagePicker, animated: true, completion: nil)
    }
    
    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
        dismiss(animated: true, completion: nil)
        let cell = tableExemple.cellForRow(at: NSIndexPath(row: 0, section: 0) as IndexPath) as! exempleCellUpload
        cell.imageExemple.image = image
    }
    
    
    }
    
    class exempleCellUpload: UITableViewCell {
    
    var delegate : ImagePickerDelegate?
    
    func pickImage(sender: AnyObject) {
        delegate?.pickImage()
    }
    
    @IBOutlet weak var imageExemple: UIImageView!
    @IBOutlet weak var labelExemple: UILabel!
    @IBOutlet weak var viewCellule: UIView!
    
    }
    

    Quand je clic sur ma cellule, j'ai bien les données associés à cette cellule mais c'est tout :/
    Aucun lancement de galerie pour choisir une photo..

  • LarmeLarme Membre

    Il faut apprendre à débuguer, savoir si les méthodes sont appelées, savoir si les objets ne sont pas nil.
    Est-ce que func pickImage(sender: AnyObject) est appelé ?
    Si c'est le cas, est-ce que le delegate est nil?
    Est-ce que du coup func pickImage() est appelé ?

  • InsouInsou Membre
    22 août modifié #5

    ça passe dans aucune fonction quand je clic sur une cellule :/

    En même temps, sur le clic d'une cellule, j'ai rien qui parle de sélectionner l'image nan ?
    C'est ça que je ne trouve pas clair avec ce code trouvé sur stackoverflow..

  • LarmeLarme Membre

    Tu as une seule sélection d'image possible, non ?

    Je ferais quelque chose comme ça:

    Ajouter dans ton modèle :
    var image?: UIImage

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
        let uneCellule = tableView.dequeueReusableCell(withIdentifier: "cellExemple") as! exempleCellUpload
    
        let exemple = tabExemple[indexPath.row]
        if let image = example.image {
            uneCellule.image = image
        } else {
            uneCellule.imageExemple.image = UIImage(named: "upload")
                if(exemple["type"].stringValue == "photo"){
            uneCellule.labelExemple.text = "Sélectionne une photo comme exemple.."
        }
        else{
            uneCellule.labelExemple.text = "Sélectionne une vidéo comme exemple.."
        }
        }
    
        return uneCellule
    }
    
    // Lorsqu'on clic sur la cellule
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.pickImage()
    }
    
    func pickImage() {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
        imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
        imagePicker.allowsEditing = false
        self.present(imagePicker, animated: true, completion: nil)
    }
    
    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
        dismiss(animated: true, completion: nil)
        guard let selectedIndexPath = tableView.indexPathForSelectedRow else { print("oops, no row selected"); return }
        //Remplace maintenant ton modèle en gardant l'image dans l'objet de tabExemple[selectedIndexPath.row]
       let currentExemple = tabExemple[selectedIndexPath.row]
       currentExample.image = image
       //Reload
        tableView.reloadRows(at: [selectedIndexPath] with: .none)
    }
    
  • InsouInsou Membre

    J'ai modifier un peu cette fonction pour en faire ceci :

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
        dismiss(animated: true, completion: nil)
        guard let selectedIndexPath = tableExemple.indexPathForSelectedRow else { print("oops, no row selected"); return }
        let cell = tableExemple.cellForRow(at: NSIndexPath(row: selectedIndexPath.row, section: 0) as IndexPath) as! exempleCellUpload
        cell.imageExemple.image = image
        tableExemple.reloadRows(at: [selectedIndexPath], with: .none)
    }
    

    Du coup, je peux bien sélectionner une photo (avec le pickImage dans la sélection de la cellule) mais il ne remplace rien.
    Il ne passe pas dans la fonction du dessus :/

    J'ai une erreur dans la console :

    [discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}
    

    Je vais googler ça, histoire de voir si je trouve quelque chose qui me débloquera..
    Si t'as une idée, n'hésite pas :D

  • LarmeLarme Membre
    Ne reload pas le cellule alors. Mais vu que tu devra repasser dans cellForRow à un moment donné, tu perdras tamodification.
  • InsouInsou Membre

    @Larme a dit :
    Ne reload pas le cellule alors. Mais vu que tu devra repasser dans cellForRow à un moment donné, tu perdras tamodification.

    Ah oui, je crois comprendre.. je vais faire des tests quand l'image se chargera bien dans la cellule déjà ^^

    J'ai modifier la fonction PickImage pour rajouter la vérification des droits de l'application sur les images..
    Voila mon code :

    func pickImage() {
        if(fonctions().checkPermissionPhoto() == true){
            // Ok on a la permission
            if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary){
                let imagePicker = UIImagePickerController()
                imagePicker.delegate = self
                imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
                imagePicker.allowsEditing = false
                self.present(imagePicker, animated: true, completion: nil)
            }
        }
        else{
            // On n'a pas la permission, on ouvre les paramètres
            let alertController = UIAlertController(title: "Erreur !", message: "Merci d'activer les paramètres pour les photos (blablabla)", preferredStyle: .alert)
            let settingsAction = UIAlertAction(title: "Paramètres", style: .default) { (_) -> Void in
                guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
                    return
                }
                if UIApplication.shared.canOpenURL(settingsUrl) {
                    UIApplication.shared.open(settingsUrl)
                }
            }
            alertController.addAction(settingsAction)
            self.present(alertController, animated: true, completion: nil)
        }
    }
    

    et la fonction checkPermissionPhoto()

    func checkPermissionPhoto() -> Bool {
    
        var autorisation = false
    
        switch PHPhotoLibrary.authorizationStatus() {
        case .authorized:
            autorisation = true
        case .notDetermined, .restricted, .denied:
            PHPhotoLibrary.requestAuthorization({
                (newStatus) in
                if newStatus ==  PHAuthorizationStatus.authorized {
                    autorisation = true
                }
                else{
                    autorisation = false
                }
            })
        }
    
        return autorisation
    }
    

    et j'ai toujours l'erreur :

    [discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}

    Du coup, je ne passe pas dans imagePickerController() :/

  • LarmeLarme Membre
    22 août modifié #10

    Tu as mis ce qu'il fallait dans le Info.plist ?

  • InsouInsou Membre

    Ouai, j'ai ajouté :
    Privacy - Photo Library Usage Description - blablabla
    Privacy - Camera Usage Description - blablabla

  • InsouInsou Membre

    Ok ça fonctionne..

    J'ai rajouté @objc devant ma fonction et ça marche ^^

    Je continue mes tests.

    Merci de ton aide :)

  • InsouInsou Membre
    22 août modifié #13

    Bon du coup maintenant j'ai un autre soucis..
    Comme t'as dû le comprendre via le code.. j'arrive sur une tableView qui génère des cellules, suivant le nombre d'images ou vidéos à choisir.

    A chaque clic sur une cellule, je regarde si c'est une image ou une vidéo qui est attendue.

    Pour les images, c'est ok, ça fonctionne.

    Et maintenant, pour les vidéos ?
    J'ai commencé un truc mais je ne sais pas trop où je vais..

    A mon avis, il me faut :

    • Choisir une vidéo
    • Récupérer une miniature d'une vidéo pour la mettre dans la cellule ?
    • Stocker la vidéo quelque part nan ? Car à un moment donné, je vais avoir besoin de les récupérer et de les envoyer..

    Pour choisir une vidéo, j'ai ajouté ça :

    protocol ImagePickerDelegate {
        func pickImage()
        func pickVideo()
    }
    

    Dans ma classe, j'ai ajouté :

    func pickVideo() {
        if(fonctions().checkPermissionPhoto() == true){
            if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary){
                let imagePicker = UIImagePickerController()
                imagePicker.delegate = self
                imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
                imagePicker.mediaTypes = ["public.movie"] // pour les vidéos
                imagePicker.allowsEditing = false
                self.present(imagePicker, animated: true, completion: nil)
            }
        }
        else{ // ouvre les paramètres de l'appli
            let alertController = UIAlertController(title: "Erreur", message: "T'ira pas plus loin tant que j'ai pas les droits sur les photos !", preferredStyle: .alert)
            let settingsAction = UIAlertAction(title: "Paramètres", style: .default) { (_) -> Void in
                guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
                    return
                }
                if UIApplication.shared.canOpenURL(settingsUrl) {
                    UIApplication.shared.open(settingsUrl)
                }
            }
            alertController.addAction(settingsAction)
            self.present(alertController, animated: true, completion: nil)
        }
    }
    
    class exempleCellUpload: UITableViewCell {
    
        var delegate : ImagePickerDelegate?
    
        func pickImage(sender: AnyObject) {
            delegate?.pickImage()
        }
        func pickVideo(sender: AnyObject) {
            delegate?.pickVideo()
        }
    
        @IBOutlet weak var imageExemple: UIImageView!
        @IBOutlet weak var labelExemple: UILabel!
        @IBOutlet weak var viewCellule: UIView!
    }
    

    En testant, ça fonctionne bien pour une image mais pas une vidéo..
    Après la sélection d'une vidéo, il ne passe pas dans imagePickerController() et je retombe sur l'erreur de tout à l'heure (avant qu'il passe dans la bonne fonction) : Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}
    D'un côté je me dis que c'est normal, vu que c'est un IMAGE picker.. et pas un vidéo picker..

    Je ne sais pas si je suis sur la bonne voie ou pas mais est ce qu'il y a une fonction à mettre pour récupérer la vidéo après ?

  • InsouInsou Membre

    Bon bah je bloque sur la récupération de la vidéo après sélection..
    Quelqu'un a une piste pour me débloquer ? :/

  • InsouInsou Membre

    Bon bah j'ai réussi :D

    J'ai remplacé ma fonction func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?)

    Par celle la :

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    
        guard let selectedIndexPath = tableExemple.indexPathForSelectedRow else { print("oops, no row selected"); return }
        let cell = tableExemple.cellForRow(at: NSIndexPath(row: selectedIndexPath.row, section: 0) as IndexPath) as! exempleCellUpload
    
        if(picker.mediaTypes.first == "public.image"){ // image
            let image = info[UIImagePickerControllerOriginalImage] as! UIImage
            cell.imageExemple.image = image
        }
        else{ // video
            let videoURL = info[UIImagePickerControllerMediaURL] as? NSURL
            do {
                let asset = AVURLAsset(url: videoURL! as URL , options: nil)
                let imgGenerator = AVAssetImageGenerator(asset: asset)
                imgGenerator.appliesPreferredTrackTransform = true
                let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(0, 1), actualTime: nil)
                let thumbnail = UIImage(cgImage: cgImage)
                cell.imageExemple.image = thumbnail
            } catch let error {
                print("*** Error generating thumbnail: \(error.localizedDescription)")
            }
        }
        self.dismiss(animated: true, completion: nil)
    }
    

    J'utilise didFinishPickingMediaWithInfo, si c'est une image, je l'a met dans la cellule, si c'est une vidéo, j'en fais une miniature que je met dans la cellule..

    Dernière question : Maintenant que mes images et vidéos sont sélectionnées dans ma tableView..
    Comment je les récupère pour les envoyer sur un serveur ?

  • Joanna CarterJoanna Carter Membre, Modérateur

    Tu ne devrais jamais "stocker" les données ou les fichiers dans les composantes visuelles.

    Tu devrais les stocker dans le modèle et les récupérer de là, pour montrer dans les cellules, pour envoyer, etc.

  • InsouInsou Membre

    Est-ce-que tu as un petit exemple ?
    Je ne suis pas sûr de comprendre ce que tu veux dire :/

  • @Insou a dit :
    Je ne suis pas sûr de comprendre ce que tu veux dire :/

    Elle veux dire MVC !

  • InsouInsou Membre

    Ouai ça j'ai cru comprendre mais est-ce-que quelqu'un peut me faire un petit exemple tout simple (ou un lien qui explique bien le truc avec des exemples) ?

    J'ai l'impression que c'est tout con comme truc et vu que c'est un nouveau projet, autant mettre les bonnes bases tout de suite.

  • LarmeLarme Membre
    24 août modifié #20

    C'est ce que je t'avais dit au départ.
    À un moment donné tableView(_ tableView:cellForRowAt) risque d'être appelé pour une cellule dont tu as changé l'image.
    Donc comment tu retiens le fait que tu as utilisé une image différente ? En utilisant ton modèle pardi !

    Si tu veux tester le cas où cela foire, ajoute des cellules, modifies une image sur une cellule, et scroll pour faire disparaitre cette cellule, puis rescrolle pour la faire apparaitre à nouveau.

    Mais pour faire ça, arrête d'utiliser JSON() à toutes les sauces.
    Utilises des customs struct/class pour représenter ton modèle.

  • InsouInsou Membre
    24 août modifié #21

    Ah oui, c'est ce que tu me disais avec ça :

    //Remplace maintenant ton modèle en gardant l'image dans l'objet de tabExemple[selectedIndexPath.row]
    

    let currentExemple = tabExemple[selectedIndexPath.row]
    currentExample.image = image

    Mais mon tabExemple est un tableau de json, je ne peux pas déclarer un UIImage dedans..
    Edit : Ah bah j'avais pas vu ton edit aussi.. je vais voir ce que je peux faire avec les customs struct/class

  • InsouInsou Membre

    C'est gooooooood, j'ai pigé le truc !

    Ce qui m'a mis sur la voie, c'est l'surtout ça :

    Si tu veux tester le cas où cela foire, ajoute des cellules, modifies une image sur une cellule, et scroll pour faire disparaitre cette cellule, puis rescrolle pour la faire apparaitre à nouveau.
    Mais pour faire ça, arrête d'utiliser JSON() à toutes les sauces.
    Utilises des customs struct/class pour représenter ton modèle.
    

    J'ai donc créer une classe avec les infos dont j'ai besoin par cellule :

    class Exemple {
        var id: Int = 0
        var type: String = ""
        var image: UIImage? = nil
        var label: String = ""
    
        init (id: Int, type: String, image: UIImage, label: String){
            self.id = id
            self.type = type
            self.image = image
            self.label = label
        }
    }
    

    J'ai remplacé mon :

    var tabExemple: [JSON] = []
    

    par :

    var tabExemple: [Exemple] = []
    

    Pour l'ajout dans le tableau, j'ai remplacé :

    tabExemple.append(JSON(["id":i, "type": "photo"]))
    

    par :

    tabExemple.append(Exemple(id:i, type: "photo",image:UIImage(named:"upload")!,label:"Sélectionne une photo comme exemple)"))
    

    Pour la récupération des infos dans cellForRowAt :

    let exemple = tabExemple[indexPath.row]
    let uneCellule = tableView.dequeueReusableCell(withIdentifier: "cellExemple") as! exempleCellUpload
    uneCellule.imageExemple.image = exemple.image
    uneCellule.labelExemple.text = exemple.label
    

    Et pour la sélection d'une image dans didFinishPickingMediaWithInfo

    let exemple = tabExemple[selectedIndexPath.row]
    guard let selectedIndexPath = tableExemple.indexPathForSelectedRow else { print("oops, no row selected"); return }
    let cell = tableExemple.cellForRow(at: NSIndexPath(row: selectedIndexPath.row, section: 0) as IndexPath) as! exempleCellUpload
    ...
    let image = info[UIImagePickerControllerOriginalImage] as! UIImage
    cell.imageExemple.image = image // affiche l'image dans la cellule
    exemple.image = image // stock dans le modele
    

    A chaque rechargement de cellule, il passe dans cellForRowAt, qui récupère l'image et le texte de la cellule dans le modèle, du coup, il n'y a plus le bug de l'image qui disparait quand on scroll :)

    Je réécris tout ça ici principalement pour moi plus tard, j'sens que ça va bien me servir ^^

    Merci pour votre aide et votre patience ^^

  • InsouInsou Membre

    Tient, question bête..

    Voici le code de mon imagePickerController, en gros, je sélectionne une image ou une vidéo..
    Ces fichiers sélectionnés doivent être stocké quelque part pour pouvoir les envoyer plus tard vers un serveur.

    Pour l'image, pas de soucis, c'est un type UIImage que je stock dans mon modèle.
    Mais pour la vidéo ? Je l'a stock avec quel type ?

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    
        guard let selectedIndexPath = tableExemple.indexPathForSelectedRow else { print("oops, no row selected"); return }
        let cell = tableExemple.cellForRow(at: NSIndexPath(row: selectedIndexPath.row, section: 0) as IndexPath) as! exempleCellUpload
        let exemple = tabExemple[selectedIndexPath.row]
    
        if(picker.mediaTypes.first == "public.image"){ // image
            let image = info[UIImagePickerControllerOriginalImage] as! UIImage
            cell.imageExemple.image = image
            exemple.imageDefis = image // stock dans le modele
        }
        else{ // video
            let videoURL = info[UIImagePickerControllerMediaURL] as? NSURL
            fonctions().consoleLog(texte:videoURL,etat:0,separateur: true)
            do {
                let asset = AVURLAsset(url: videoURL! as URL , options: nil)
                let imgGenerator = AVAssetImageGenerator(asset: asset)
                imgGenerator.appliesPreferredTrackTransform = true
                let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(0, 1), actualTime: nil)
                let thumbnail = UIImage(cgImage: cgImage)
                cell.imageExemple.image = thumbnail
                exemple.imageDefis = thumbnail  // stock l'image dans le modele
                // Stocker la vidéo dans le modèle ici ??
            } catch let error {
                print(error.localizedDescription)
            }
        }
    
       cell.labelExemple.text = "ok"
       exemple.labelDefis = "ok"
    
        self.dismiss(animated: true, completion: nil)
    }
    
  • Joanna CarterJoanna Carter Membre, Modérateur
    24 août modifié #24

    Voici un exemple:

    struct Item
    {
      var text: String
    
      var image: UIImage?
    }
    
    class TableViewCell: UITableViewCell
    {
      @IBOutlet weak var lbl: UILabel!
    
      @IBOutlet weak var img: UIImageView!
    
      public var item: Item?
      {
        didSet
        {
          lbl.text = item?.text
    
          img.image = item?.image
        }
      }
    }
    
    class ViewController: UITableViewController
    {
      enum Error : Swift.Error
      {
       case unableToDequeueCell
      }
    
      var model: [Item] = .init()
    
      var selectedItemIndex: Int?
    
      @IBAction func addItem(_ sender: UIBarButtonItem)
      {
        let item = Item(text: "\(model.count + 1)", image: nil)
    
        model.append(item)
    
        tableView.reloadData()
      }
    
      override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
      {
        return model.count
      }
    
      override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
      {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? TableViewCell else
        {
          fatalError("Unable to dequeue cell")
        }
    
        cell.item = model[indexPath.row]
    
        return cell
      }
    
      override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
      {
        return 148.0
      }
    
      override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
      {
        selectedItemIndex = indexPath.row
    
        let imagePicker = UIImagePickerController()
    
        imagePicker.delegate = self
    
        imagePicker.sourceType = .photoLibrary
    
        imagePicker.allowsEditing = false
    
        self.present(imagePicker, animated: true, completion: nil)
      }
    }
    
    extension ViewController : UIImagePickerControllerDelegate, UINavigationControllerDelegate
    {
      func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
      {
        guard let selectedItemIndex = selectedItemIndex,
              let pickedImage = info[.originalImage] as? UIImage else
        {
          return
        }
    
        model[selectedItemIndex].image = pickedImage
    
        let indexPath = IndexPath(row: selectedItemIndex, section: 0)
    
        tableView.reloadRows(at: [indexPath], with: .automatic)
    
        self.selectedItemIndex = nil
    
        dismiss(animated: true, completion: nil)
      }
    }
    
  • Je partage bien ce point de vue, en fait dès que ça évolue on a tout intérêt a faire une classe (ou une extension) de tout.

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