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)
(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 ???
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
}
}
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]
}
}
}
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
.
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!!