affichage/instanciation UIViewController depuis cellule UITableView (segue storyboard)

toolsDevtoolsDev Membre
février 2017 modifié dans Objective-C, Swift, C, C++ #1

Bonjour,


 


J'aimerais comprendre et arriver à  ouvrir une UIViewController depuis le clic d'une cellule UITableView, en utilisant le storyboard.


 


En gros, j'ai une UITableView avec du contenu (cellule sans label juste la cellule et du texte) et au clic de cette derrière je souhaiterais afficher/instancier une UIViewController en récupérant le bon index précédemment sélectionné.


 


Donc, j'ai bien utilisé une segue (showItemSegue) entre UITableView(cellule) et mon UIViewController(View) (dans storyboard mes vues sont bien linker à  des class)


 


dans le code de ma UITableView tout me semble bon (?):



import UIKit

class TableViewController: UITableViewController
{
var table = String()

override func viewDidLoad()
{
super.viewDidLoad()
}

override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.dataTable.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = UITableViewCell(style: .default, reuseIdentifier: "cellule")
cell.textLabel?.text = self.dataTable[indexPath.row]
return cell
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if (segue.identifier == "showItemSegue")
{

let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let itemViewController: ItemViewController = storyBoard.instantiateViewController(withIdentifier: "showItemSegue") as! ItemViewController
self.navigationController?.pushViewController(itemViewController, animated: true)

itemViewController = ItemViewController()
itemViewController.table = self.table
}
}
}

et dans mon UIViewController, rien de spécial pour le moment, juste des tests d'affichagent des données récupérées depuis la segue de ma UITabelView


 


Mais pour le moment rien ne fonctionne, c'est à  dire qu'aucun UIViewController ne s'affiche... Je ne pense pas qu'un "push" soit nécessaire ? le storyboard via mon navigationController devrais s'en chargé avec la segue surtout, non ?


 


Merci à  tous :)


 


Edit:


Bon, je viens de testé ce ci :



override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let indexPath = tableView.indexPathForSelectedRow

let currentCell = tableView.cellForRow(at: indexPath!)! as UITableViewCell

self.data = currentCell.textLabel!.text!

let vc = ItemViewController()
present(self.vc, animated: true, completion: nil)
}

J'ai une vue qui s'ouvre mais le background est black, alors que je ne définit pas cette couleur dans mon projet (storyboard ou via du code)


et mes données passées via la segue (en console) ne s'affiche pas. 


Réponses

  • Bonjour, 


     


    Tu as juste oublier d'implementer la méthode qui permet de detecter le click sur la cell, rajoute ce code :



    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    //tu ecri ton code ici
    performSegue(withIdentifier: "showItemSegue", sender: indexPath)
    }
  • toolsDevtoolsDev Membre
    février 2017 modifié #3

    alors avec ce code :



    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
    let indexPath = tableView.indexPathForSelectedRow

    let currentCell = tableView.cellForRow(at: indexPath!)! as UITableViewCell

    self.data = currentCell.textLabel!.text!

    present(self.vc, animated: true, completion: nil)

    performSegue(withIdentifier: "showItemSegue", sender: indexPath)
    }

    et dans la méthode prepare for segue :



    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
    if (segue.identifier == "showItemSegue")
    {
    self.vc.table = self.table
    self.vc.data = self.data
    }

    j'ai une erreur de compilation :



    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
    'Receiver (<Projet.TableViewController: 0x7fec4f00cd70>) has no segue with identifier 'showItemSegue''


    je viens de vérifier dans mon storyboard le nom est bien "showItemSegue"... je comprends pas du coup :(


  • Joanna CarterJoanna Carter Membre, Modérateur
    Tu as trop de code et pas assez de storyboard ;) Demain, je te prepare un petit projet pour te montrer.
  • toolsDevtoolsDev Membre
    février 2017 modifié #5

    salut,


     


    lol ben j'essais de tout viré (pour suivre tes conseils) mais pas facile, suis un adepte du code... je trouve ça plus "maitrise"


    en tout cas je te le redis encore ! mais merci beaucoup pour ton aide !


     


    je post la dernière version de ce que j'ai fait histoire d'être clair :



    import UIKit

    class TableViewController: UITableViewController
    {
    var table = String()
    var dataTable = [String]()
    var data = String()
    let vc = ItemViewController()

    override func viewDidLoad()
    {
    super.viewDidLoad()

    title = self.table
    }

    override func didReceiveMemoryWarning()
    {
    super.didReceiveMemoryWarning()
    }


    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
    return self.dataTable.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
    let cell = UITableViewCell(style: .default, reuseIdentifier: "cellule")

    cell.textLabel?.text = self.dataTable[indexPath.row]
    return cell
    }


    override func tableView(_ tableView: UITableView, didSelectRowAt IndexPath: IndexPath)
    {
    let currentCell = tableView.cellForRow(at: IndexPath)! as UITableViewCell

    self.data = = currentCell.textLabel!.text

    let itemViewController = self.storyboard!.instantiateViewController(withIdentifier: "showItemSegue") as! ItemViewController
    let navController = UINavigationController(rootViewController: itemViewController)
    present(navController, animated:true, completion: nil)

    performSegue(withIdentifier: "showItemSegue", sender: indexPath)// ?
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
    if (segue.identifier == "showItemSegue")
    {
    self.vc.table = self.table
    self.vc.data = self.data
    }
    }
    }



    mon storyboard complet :


    uzve.png


  • Joanna CarterJoanna Carter Membre, Modérateur
    Non, non, non :) Tu confonds plusieurs choses. Attends demain pour que je t'éclaircisse.
  • très bien ;)


  • De mémoire on évite de créer un segue dans le Storyboard depuis une cellule vers un autre UIViewController, cela risque de bypasser le prepareForSegue:sender: Mais on lie plutôt les 2 UIViewControllers entre eux.


     


    Quand crées un segue et l'utilises, pas besoin de faire de créer le prochain UIViewController dans prepareForSegue:sender:.


    Donc tout ça :


    let itemViewController = self.storyboard!.instantiateViewController(withIdentifier: "showItemSegue") as! ItemViewController

    let navController = UINavigationController(rootViewController: itemViewController)

    present(navController, animated:true, completion: nil)


  • toolsDevtoolsDev Membre
    février 2017 modifié #9

    comme je disais (je crois) si je fais ça :



    override func tableView(_ tableView: UITableView, didSelectRowAt IndexPath: IndexPath)
    {
    let currentCell = tableView.cellForRow(at: IndexPath)! as UITableViewCell
    self.data = currentItem!

    let itemViewController = ItemViewController()
    present(itemViewController, animated:true, completion: nil)
    }

    J'ai une nouvelle vue qui s'affiche, mais, elle est noir et vide, donc je ne vois pas d'ou elle provient, puisque dans mon code ou storyboard, à  aucun moment je donne un background black et pas de bouton "back" (navigation)


    En tout cas c'est pas une instance de la mienne...


    mais juste pour les tests j'ai créer une pop up et là  tout fonctionne bien, c'est à  dire que via cette méthode la pop up s'affiche bien avec mes données sélectionnées.


     


    ça je le sent pas, ça me fait tout planté... En plus, il est déjà  dans le storyboard, bref je verrais demain, là , je comprends pas trop.



    performSegue(withIdentifier: "showItemSegue", sender: indexPath)

    Edit:


    j'ai aussi oublié de précisez que mon point d'entrée est le navigationController, car je veux une UIViewControler (ou ce trouve mes boutons) qui mène (au clic) à  ma UITableView (là  tout fonctionne bien, données affichées) et au clic de la cellule ouverture d'une UIViewController pour le détail des data :)


  • Il faut comprendre la différence entre un segue et l'ancienne méthode plus manuelle.


     


    Quand tu veux présenter un nouvel écran, voici les 3 étapes :


    • Créer le ViewController


    • Faire différents paramétrages sur ce dernier.


    • Aller à  ce view controller.


     


    Ce que te permet le segue (et les storyboards)


    La création n'est pas à  faire par code.


    Aller à  ce view controller n'est pas à  faire par code.


     


    Le segue sait qui est lié, et il a en propriété destinationViewController qui est celui que tu avais besoin de créer précédemment.


    Les paramétrages sont à  faire dans le prepareForSegue:sender:. Là , une fois que tu as identifié ton segue (via sa propriété identifier), tu lui configure le prochain view controller.


    En général :



    if ([[segue identifier] isEqualToString:@SegueVoulu])
    {
    //On ne fait pas l'alloc/init du prochain ViewController car le segue l'a déjà  !
        ClassDeMonProchainViewController *nextVC = [segue destinationViewController];
        [nextVC setParametre1:quelquechose1];
        ...
        [nextVC setParametreN:quelquechoseN];
    //Et on appelle pas le presentViewController, ou pushViewController ici !
    }

    La manière dont il est présenté, c'est dans les propriété du segue dans le Storyboard : Push, Show, etc, il saura lui-même que faire.


     


    Qu'est-ce que ça apporte concrètement : Pourquoi utiliser un Storyboard et les segues qui vont avec ?


    Déjà , tu sais à  quoi ressembles l'applications. Tu as rapidement une vue d'ensembles des cheminements, des users-stories.


    Tu évites moult initWithNibName (ou assimilés) pour la première étape.


    La manière dont il est présenté est automatisée. Avant, il fallait se dire que si mon ViewController de départ avait une NavigationBar, il fallait faire un Push, alors que maintenant, il se sait déjà .


     


    Tu peux continuer de faire toi-même des alloc/init d'un ViewController, son paramétrage, et sa présentation, mais c'est en plus rare, à  la marge.


     


     


    Pour en revenir à  ton précédent code :


        let itemViewController = ItemViewController()

        present(itemViewController, animated:true, completion: nil)


    Là , tu as créé un nouveau ItemViewController, mais clairement pas celui qui est dans un Xib ou dans ton Storyboard. Il n'y a pas eu d'appel (caché) à  initWitCoder/awakeFromNib.


  • toolsDevtoolsDev Membre
    février 2017 modifié #11

    oui tu as raison je n'instanciais pas le bon objet, si j'ai bien compris maintenant je devrais faire ceci :



    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {

    if segue.identifier == "showItemSegue"
    {
    if let itemViewController = segue.destination as? ItemViewController
    {
    // pointage du bon objet sur le storyboard et vérifié par le segue :
    itemViewController.table = self.table
    itemViewController.data = self.data
    }
    }
    }


    Mais, là  encore ou je comprends toujours pas et ou ça plante (erreur de segue non reconnu, comme plus haut) c'est donc ici :



    override func tableView(_ tableView: UITableView, didSelectRowAt IndexPath: IndexPath)
    {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let itemViewController = storyboard.instantiateViewController(withIdentifier: "showItemSegue") as! ItemViewController

    self.navigationController!.present(itemViewController, animated: false, completion: nil)
    }


    là , cette fois c'est le bon objet qui est pointé... Donc, d'après moi, j'ai un soucis dans mon storyboard, ayant tout vérifié et n'ayant pas grand chose je sèche .


  • Il ne trouve pas de segue avec comme identifiant showItemSegue. Donc il est très probable que ton identifiant ne corresponde pas ou n'est pas renseigné. Si tu cliques sur la liaison entre ton premier controller et celui vers lequel tu veux aller dans ton storyboard, dans le panneau à  droite tu dois renseigner l'identifiant du segue. À priori, puisque dans ton code c'est showItemSegue, tu dois le nommer lui aussi showItemSegue. Les deux doivent être identiques.


  • toolsDevtoolsDev Membre
    février 2017 modifié #13

    salut et merci,


     


    le soucis est qu'ils correspondent bien.


    je drag de la cellule de ma tableView et je drop sur la view de mon ViewController, ensuite je donne comme id "showItemSegue"


    ViewController(ItemViewController) du storyboard est bien associé à  ma classe swift ItemViewController qui lui correspond


     


    donc, je vois plus trop là ,


  • LarmeLarme Membre
    février 2017 modifié #14

    J'ai oublié de préciser précédemment.

    Du coup, le prepareForSegue:sender: ne fait que préparer le terrain.

    Il faut que tu dises à  ton code :

    Fais le segue avec tel identifiant, via la méthode performSegue(withIdentifier identifier:sender:)

    Avant d'aller à  l'écran suivant, prepareForSegue:sender: est appelé.

    Si tu as des paramétrages à  faire, c'est là  qu'il faut le faire.

     

     

     

     

    Code non-certifié (car je ne code pas en Swift)



    override func tableView(_ tableView: UITableView, didSelectRowAt IndexPath: IndexPath)
        {
            self.performSegue(withIdentifier identifier:"showItemSegue" sender:nil)
        }

    Mais cela ne résoudra pas le problème de segue avec identifiant mauvais.


     


    On est bien d'accord :


    Le segue, c'est la p'tite flèche qui lie 2 UIViewControllers.


    Ce dernier a son propre identifiant.


    Un UIViewController a aussi un identifiant.


     


    Vu ton code, j'ai l'impression que tu mets l'identifiant du prochain ViewController et pas du segue.

  • toolsDevtoolsDev Membre
    février 2017 modifié #15

    Et bien pour la flèche, elle part du TableViewController (de ça cellule pour être précis) et va sur la View de mon UIViewController, la segue qui les relies à  bien pour identifier "showItemSegue"


     


    Je ne peut de toute façon pas mettre une segue sur une vue sans "la flèche"


    une "flèche" = segue 


     


       cellule                                                                  View


    UItableView


    > UIVewController

                        identifier : "showItemSegue"


     


    donc, je ne vois pas trop... Les "identifier" son pour moi les segues ? :( et les ID storyboard je ne m'en sert pas.


     


    je vais tout supprimer et refaire un nouveau projet, au cas ou j'aurais fait une bêtise dans le storyboard ...


     


    Edit :


    pour plus de clarté :


    lkia.pngpour l'erreur à  la compilation, je n'ai plus d'erreur d'identifier à  présent, mais un plantage sans 'info' juste un soucis de "mauvaise instruction thread"


    nouveau code :



    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
    // ERREUR let itemViewController:ItemViewController = self.storyboard?.instantiateViewController(withIdentifier: "showItemSegue") as! ItemViewController
    // ERREUR
    itemViewController.row = self.dataTable[indexPath.row]
    itemViewController.table = self.table
    self.present(itemViewController,animated:true,completion:nil)
    performSegue(withIdentifier: "showItemSegue", sender: indexPath)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
    // rien puisque je fais déjà  tout au dessus .... (?)
    }


  • LarmeLarme Membre
    février 2017 modifié #16

    pour l'erreur à  la compilation, je n'ai plus d'erreur d'identifier à  présent, mais un plantage sans 'info' juste un soucis de "mauvaise instruction thread"
    nouveau code :

        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
    // ERREUR let itemViewController:ItemViewController = self.storyboard?.instantiateViewController(withIdentifier: "showItemSegue") as! ItemViewController
    // ERREUR
    itemViewController.row = self.dataTable[indexPath.row]
    itemViewController.table = self.table
    self.present(itemViewController,animated:true,completion:nil)
    performSegue(withIdentifier: "showItemSegue", sender: indexPath)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
    // rien puisque je fais déjà  tout au dessus .... (?)
    }

    Non et non !
     Tu t'obstines à  créer ton viewcontroller. et à  le présenter toi-même ! ARRàŠTE!
     
    D'ailleurs instantiateViewController(withIdentifier: "showItemSegue"), c'est l'identifier du segue que tu mets, alors qu'il attend l'un d'une ViewController !
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
        {
             performSegue(withIdentifier: "showItemSegue", sender: indexPath)
        }
            override func prepare(for segue: UIStoryboardSegue, sender: Any?)
        {
            if (segue.identifier == "showItemSegue")
            {
                let indexPath = self.maTableView.indexPathForSelectedRow //Tu retrouves ici l'indexPath selected
                itemViewController.row = self.dataTable[indexPath.row]
                itemViewController.table = self.table
            }
       }
    Logique :
    À faire dans le STORYBOARD:
    Créer un Segue reliant deux ViewControllers.
    Donner un identifiant à  ce segue
    Modifier sa présentation si nécessaire.

    À faire dans le CODE :
    Quand tu veux changer d'écran, appeler au bon moment performSegue(withIdentifier:sender:)
    Cela va appeler tout seul prepare(for segue:sender:).
    Là , donner les paramètres qu'il faut au prochain viewcontroller.

    Soit c'est l'heure tardive, j'explique mal ou y'a une coquille dans mes explications précédentes, soit tu ne lis que la moitié de ce qui t'intéresse.
  • Non, non je m'obstine pas C'est moi qui n'avais pas compris le coup du Segue identifier ET le fait qu'il attendait le nom de mon ViewController... Tu te doutes bien que si j'ai sciement fait plusieurs fois la même erreur, c'est qu'un souci de compréhension était présent, je ne voulais bien sûr pas t'agacer...


    Et à  tord, je pensais que la méthode instanciait le bon automatiquement ! Donc, oui je n'avais juste pas pigé cette méthode...


    la, j'ai pigé !


    Je verrais tout ça demain.

    Dure journée, ceci explique cela aussi ...


    Merci,
  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2017 modifié #18

    Bonjour


     


    Je commence avec le storyboard :


     


  • salut ;)


     


    je regarde tout ça merci,


  • Joanna CarterJoanna Carter Membre, Modérateur

    Le code :



    class TableViewController : UITableViewController
    {
    // liste des noms des tables
    let tableData = ["Un", "Deux", "Trois"]

    // dictionnaire des données des tables avec les noms comme clés
    let itemData = ["Un" : ["Un1", "Un2", "Un3"], "Deux" : ["Deux1", "Deux2", "Deux3"], "Trois" : ["Trois1", "Trois2", "Trois3"]]

    // pour noter l'indexPath sélectionné quand on clique sur une cellule
    private var selectedIndexPath: IndexPath?

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
    // nombre de tables
    return tableData.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)

    // mettre le nom de la table dans la cellule
    cell.textLabel?.text = tableData[indexPath.row]

    return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
    // noter l'indexPath du rang
    self.selectedIndexPath = indexPath

    self.performSegue(withIdentifier: "showItemSegue", sender: nil)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
    // vérifier que le nom de segue est bon
    guard segue.identifier == "showItemSegue",
    // vérifier qu'on à  assigné l'indexPath du rang
    let indexPath = selectedIndexPath,
    // faire le "cast" de UIViewController vers ItemViewController
    let itemViewController = segue.destination as? ItemViewController else
    {
    // en cas d'échec, ne rien faire
    return
    }

    // récupérer le nom de la table pour l'indexPath
    let tableName = tableData[indexPath.row]

    // récupérer les données pour la table
    guard let itemData = itemData[tableName] else
    {
    return
    }

    // mettre le nom de la table en tuple avec la liste des données pour la table
    // et les passer vers le ItemViewController
    itemViewController.itemsData = (tableName, itemData)
    }
    }


    class ItemViewController : UITableViewController
    {
    // tuple pour tenir le nom de la table et ses données
    var itemsData: (tableName: String, items: [String])?
    {
    didSet
    {
    // lorsque la var est assigné, assigner le nom de la table comme titre
    // pour le contrôleur
    self.navigationItem.title = itemsData?.tableName

    // instituer le rechargement de la tableView
    self.tableView.reloadData()
    }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
    return itemsData?.items.count ?? 0
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
    let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath)

    cell.textLabel?.text = itemsData?.items[indexPath.row]

    return cell
    }
    }

    Et, c'est tous.


  • Joanna CarterJoanna Carter Membre, Modérateur

    Projet complet ci-joint


  • toolsDevtoolsDev Membre
    février 2017 modifié #22

    juste une petite question comment tu as fait pour nommé tes objet dans le storyboard ?


    je veux parlé de ta tableView et de ItemViewController.


     


    Dans le cartouche du dessus on vois leur nom : Tables (tableViewController) et Item View Controller (tableViewController) ?


     


    Sinon, je voulais te dires que si j'avais plusieurs segue ("J'ai fait deux segues du UINavigationController") s'étais pour ma fameuse histoire de point d'entrée sur une ViewController puis une tableViewController (et non comme ton exemple directement start l'application sur une tableViewController) Je ne sais pas faire autrement...


     


    Je refais tout pour bien comprendre là  ! Beaucoup de chose était confuse pour moi, oui...


    Edit: et merci pour le Zip ! je vais quand même le refaire à  la mano pour mieux comprendre.


     


    Merci beaucoup ! !  !


  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2017 modifié #23

    Tu ouvres le projet que j'ai mis en pièce-jointe et tu l'examines  :-*


     




    Dans le cartouche du dessus on vois leur nom : Tables (tableViewController) et Item View Controller (tableViewController) ?




     


    "Tables" vient du fait que j'ai nommé le navigationItem du TableViewController. Dans le Document Outline, tu vois un bouton qui contient une flèche vers la gauche ; cliques là  et tu verras dans le Attributes Inspector, que Title contient Tables.


     


    "Item View Controller" vient du nom de la classe du contrôleur, automatiquement fait par Xcode. Ce n'est pas visible à  runtime.


     




    Sinon, je voulais te dires que si j'avais plusieurs segue ("J'ai fait deux segues du UINavigationController") s'étais pour ma fameuse histoire de point d'entrée sur une ViewController puis une tableViewController (et non comme ton exemple directement start l'application sur une tableViewController) Je ne sais pas faire autrement...




     


    Si tu mettais deux segues d'un UINavigationController, c'est en disant que tu veuilles faire deux choses au même temps ou que tu veuilles avoir une choix, mais on ne peut pas le faire.


     


    Bien sûr que tu puisses avoir plusieurs segues qui proviennent d'un viewController d'autre type mais, UINavigationController, c'est spécial .


  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2017 modifié #24


    et merci pour le Zip ! je vais quand même le refaire à  la mano pour mieux comprendre.




     


    Je n'attendais que tu fasses autrement  8--)


  • toolsDevtoolsDev Membre
    février 2017 modifié #25

    coucou,


     


    bon j'ai bien étudier ton code et je pense en avoir pigé l'essentielle !


     


    Cependant j'ai une question, concernant mon idée de démarrer mon application sur une UIVIewController (avec un navigationController de linker sur lui) et que cette vue via des boutons (coder et donc pas dans le storyboard) je veux aller sur une UITableViewController,


    tu m'avais déconseiller (comme j'avais fait) de tirer 2 segues du navigationController, une vers le point d'entrée UIViewController et l'autre vers la UITableViewController.


    Mais du coup comment le faire ? (storyboard)


     


     


    PS:


    je vais aussi commencer à  m'intéresser à  UICollectionView, mais pour mon projet je ne le ferais pour les boutons (tables)


  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2017 modifié #26

    Dans ton image du storyboard, tu montres deux segues de la UINavigationController. Comme je t'ai déjà  dit, la UINavigationController fait une pile ou stack ; du coup, on ne peut pas avoir qu'un segue comme rootViewController.


     


    Alors, pour faire ce que tu veux, il ne faut que remplacer la première UITableViewController avec une UIViewController avec tes "boutons".


     


    Mais là , je te déconseillerais fortement. Tu as fait un projet d'essaie pour voir ce qui se passe avec les boutons si tu fais pivoter le simulateur (menu Hardware | RotateLeft/Right) ?


     


    Sans autolayout (possible mais pénible en code) les boutons ne suivent pas la rotation et ne changeront pas leurs agencement.


     


    Si tu ne veux pas utiliser la UICollectionView, tu a déjà  la UITableView, qui fait, comme je t'ai montré, un rang par table name


  • Joanna CarterJoanna Carter Membre, Modérateur

    C'est facile avec UICollectionViewController :



    class CollectionViewCell: UICollectionViewCell
    {
    @IBOutlet private weak var label: UILabel!

    var tableName: String?
    {
    didSet
    {
    self.label.text = tableName
    }
    }
    }


    class CollectionViewController: UICollectionViewController
    {
    let tableData = ["Un", "Deux", "Trois"]

    let itemData = ["Un" : ["Un1", "Un2", "Un3"], "Deux" : ["Deux1", "Deux2", "Deux3"], "Trois" : ["Trois1", "Trois2", "Trois3"]]

    private var selectedIndexPath: IndexPath?

    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
    {
    self.selectedIndexPath = indexPath

    self.performSegue(withIdentifier: "showItemSegue", sender: nil)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
    guard segue.identifier == "showItemSegue",
    let indexPath = selectedIndexPath,
    let itemViewController = segue.destination as? ItemViewController else
    {
    return
    }

    let tableName = tableData[indexPath.row]

    guard let itemData = itemData[tableName] else
    {
    return
    }

    itemViewController.itemsData = (tableName, itemData)
    }

    // MARK: UICollectionViewDataSource

    override func numberOfSections(in collectionView: UICollectionView) -> Int
    {
    return 1
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
    return tableData.count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell

    cell.tableName = tableData[indexPath.item]

    return cell
    }
    }

    Et, dans le storyboard :


     


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