web-dev-qa-db-fra.com

Envoyer des données de TableView à DetailView Swift

J'essaie peut-être de faire l'une des choses les plus simples et les plus déroutantes pour moi jusqu'à maintenant Je veux développer ma propre application. Pour ce faire, j'ai besoin de pouvoir passer des informations en fonction de l'utilisateur de la rangée, cliquez (c'est la langue Swift)

Nous avons un RootViewController (vue table) et un DetailViewController (avec 1 étiquette et 1 image) enter image description here

(notre point de vue)

Voici le code: 

@IBOutlet weak var tableView: UITableView!


var vehicleData : [String] = ["Ferrari 458" , "Lamborghini Murcielago" , "Bugatti Veyron", "Mercedes Benz Biome"]

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    var nib = UINib(nibName: "TableViewCell", bundle: nil)

    tableView.registerNib(nib, forCellReuseIdentifier: "cell")



}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return vehicleData.count
}



func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {


    let cell:TableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as TableViewCell

    cell.lblCarName.text = vehicleData[indexPath.row]

    cell.imgCar.image = UIImage(named: vehicleData[indexPath.row])

    return cell   
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    performSegueWithIdentifier("DetailView", sender: self)
}

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if(segue.identifier == "DetailView") {

        var vc = segue.destinationViewController as DetailViewController

    }

}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 100
}

Classe TableViewCell personnalisée (possède un fichier xib avec une cellule)

class TableViewCell: UITableViewCell {


@IBOutlet weak var lblCarName: UILabel!

@IBOutlet weak var imgCar: UIImageView!

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

class DetailViewController: UIViewController {



    @IBOutlet weak var lblDetail: UILabel!

    @IBOutlet weak var imgDetail: UIImageView!

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

La question est: 

si l’utilisateur clique sur Ferrari 458, le détail détaillé dans DetailViewController indique ce qui suit: La Ferrari 458 est une super voiture capable d’atteindre une vitesse de 325 km/h ...... (ce que nous voulons) et imgDetail serait capable de montrer une image (ce que nous voulons) de la voiture

Si l'utilisateur clique sur Bugatti Veyron, le lblDetail nous le montre: Bugatti Veyron est une machine parfaite et super sportive. C'est l'une des voitures les plus rapides du monde ....

imgDetail nous montre une image de cette voiture

Même chose avec toutes les voitures en fonction de la rangée sur laquelle nous avons cliqué

Je sais que le travail tourne autour de prepareForSegue dans le premier contrôleur de vue, mais j’essayais de nombreuses façons de le rendre possible et tout se passe bien.

Comment pouvons-nous faire cela ???

17
FactorJose

Voici l'exemple pour vous:

var valueToPass:String!

func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
    println("You selected cell #\(indexPath.row)!")

    // Get Cell Label
    let indexPath = tableView.indexPathForSelectedRow!
    let currentCell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell

    valueToPass = currentCell.textLabel.text
    performSegueWithIdentifier("yourSegueIdentifer", sender: self)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){

    if (segue.identifier == "yourSegueIdentifer") {
        // initialize new view controller and cast it as your view controller
        var viewController = segue.destinationViewController as AnotherViewController
        // your new view controller should have property that will store passed value
        viewController.passedValue = valueToPass
    }
}

Mais n'oubliez pas de créer une variable passedValue dans votre DetailViewController.

Ceci est juste un exemple de transmission de données d'un viewController à un autre et vous pouvez transmettre des données avec cet exemple selon vos besoins.

Et pour plus d'informations, référez-vous à ces liens.

Passage de valeurs entre ViewControllers en fonction de la sélection de liste dans Swift

Utilisez la méthode didSelectRowAtIndexPath ou prepareForSegue pour UITableView?

Swift: passez l'étiquette UITableViewCell au nouveau ViewController

https://teamtreehouse.com/forum/help-Swift-segue-with-variables-is-not-working

Peut-être que cela vous aidera.

Swift 3.0

var valueToPass:String!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("You selected cell #\(indexPath.row)!")

    // Get Cell Label
    let indexPath = tableView.indexPathForSelectedRow!
    let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell

    valueToPass = currentCell.textLabel?.text
    performSegue(withIdentifier: "yourSegueIdentifer", sender: self)
}

func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){

    if (segue.identifier == "yourSegueIdentifer") {
        // initialize new view controller and cast it as your view controller
        var viewController = segue.destination as! AnotherViewController
        // your new view controller should have property that will store passed value
        viewController.passedValue = valueToPass
    }
}
39
Dharmesh

Cela peut être une autre solution, sans beaucoup de code dans la méthode didSelectRowAtIndexPath . Même si elle peut sembler plus propre et que nous n’avons pas besoin d’une variable supplémentaire valueToPass, elle n’est peut-être pas une pratique recommandée, car censé être l'objet réel qui a initié la transition (ou nul).

// MARK: UITableViewDelegate methods

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)

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

// MARK: UIViewController methods

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "goToSecondVC" {    
        if segue.destination.isKind(of: CarDetailsController.self) {
            let secondVC = segue.destination as! CarDetailsController

            let indexPath = sender as! IndexPath

            secondVC.passedValue = carsArray[indexPath.row]
        }
    }
}
3
ppalancica

Si vous faites glisser une séquence de la cellule prototype (dans le Générateur d'interface) vers votre prochain contrôleur View et définissez son identificateur de séquence sur "Votre identificateur de séquence", vous pouvez également le faire avec ce raccourci:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "Your Segue Identifier" {
        let cell = sender as! YourCustomCell
        let vc = segue.destination as! PushedViewController
        vc.valueToPass = cell.textLabel?.text // or custom label
    }
}

Et vous n'avez pas non plus besoin de performSegueWithIdentifier() dans didSelectRowAtIndexPath(), ni de cette méthode Table View.

Dans PushedViewController.Swift (le prochain contrôleur de vue):

var valueToPass: String!

override func viewDidLoad() {
    super.viewDidLoad()
    yourLabel.text = valueToPass
}

Il est important de définir la valeur de l'étiquette après l'initialisation à partir du storyboard. Cela signifie que vous ne pouvez pas définir le libellé directement dans la fonction prepareForSegue() du contrôleur de vue précédent, vous devez donc le transmettre avec valueToPass.

1
Teodor Ciuraru

C’est simple, j’ajoute un énoncé à la réponse ci-dessus . Pour obtenir le nom du véhicule sélectionné dans l’étiquette de la vue de détail,

lblDetail.text = passéeValue

vous pouvez ajouter ce code de ligne dans viewDidLoad () func de votre vue détaillée. passéeValue contient le nom de la voiture que l'utilisateur a sélectionnée (attribuer dans prepareForSegue). Vous pouvez ensuite l'affecter à votre étiquette detailedView.

J'espère que ça aide!!

0