[SWIFT] Selection d'une image dans une cellule (tableview)
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 ?
Mots clés:
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
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 ?
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 :
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..
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é ?ç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..
Tu as une seule sélection d'image possible, non ?
Je ferais quelque chose comme ça:
Ajouter dans ton modèle :
var image?: UIImage
J'ai modifier un peu cette fonction pour en faire ceci :
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 :
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
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 :
et la fonction checkPermissionPhoto()
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()
Tu as mis ce qu'il fallait dans le Info.plist ?
Ouai, j'ai ajouté :
Privacy - Photo Library Usage Description - blablabla
Privacy - Camera Usage Description - blablabla
Ok ça fonctionne..
J'ai rajouté @objc devant ma fonction et ça marche ^^
Je continue mes tests.
Merci de ton aide
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 :
Pour choisir une vidéo, j'ai ajouté ça :
Dans ma classe, j'ai ajouté :
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 ?
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 ?
Bon bah j'ai réussi
J'ai remplacé ma fonction func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?)
Par celle la :
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 ?
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.
Est-ce-que tu as un petit exemple ?
Je ne suis pas sûr de comprendre ce que tu veux dire
Elle veux dire MVC !
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.
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.
Ah oui, c'est ce que tu me disais avec ça :
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
C'est gooooooood, j'ai pigé le truc !
Ce qui m'a mis sur la voie, c'est l'surtout ça :
J'ai donc créer une classe avec les infos dont j'ai besoin par cellule :
J'ai remplacé mon :
par :
Pour l'ajout dans le tableau, j'ai remplacé :
par :
Pour la récupération des infos dans cellForRowAt :
Et pour la sélection d'une image dans didFinishPickingMediaWithInfo
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 ^^
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 ?
Voici un exemple:
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.