I'm trying to do maybe one of the simplest and more confusing things for me until now I wanna develop my own App , and in order to do it I need to be able to passing some information depending of which row user click (it's Swift lenguage)
We have a RootViewController(table view) and a DetailViewController (with 1 label and 1 image)
(our view)
Here is the 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
}
Custom TableViewCell class (has a xib File with cell)
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()
}
The question is:
if user click Ferrari 458 , the lblDetail in DetailViewController would show: Ferrari 458 is a super car which is able to reach 325 km/ h ...... (whatever we want) and imgDetail would be able to show an image (whatever we want) of the car
If user click Bugatti Veyron now the lblDetail show us: Bugatti Veyron is a perfect and super sport machine. It's one of the fastest car in the world....
imgDetail show us an image of this car
Same thing with all cars depending which row we have clicked
I know the work is around prepareForSegue func in first View Controller but i was trying a lot of different ways to make it possible and anything runs ok
How we can do this???
To completely prevent selection of the UITableViewCell , have your UITableViewDelegate implement tableView:willSelectRowAtIndexPath: . From that method you can return nil if you do not want the row to be selected. This prevents the row from being selected and tableView:didSelectRowAtIndexPath: from being called.
Swift version: 5.6. Index paths describe an item's position inside a table view or collection view, storing both its section and its position inside that section.
Here is the example for you:
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
}
}
But don't forget to create a passedValue
variable into your DetailViewController
.
This is just an example of passing data from one viewController to another and you can pass data with this example as you need.
And for more info refer this links.
Passing values between ViewControllers based on list selection in Swift
Use didSelectRowAtIndexPath or prepareForSegue method for UITableView?
Swift: Pass UITableViewCell label to new ViewController
https://teamtreehouse.com/forum/help-swift-segue-with-variables-is-not-working
May be this will help you.
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
}
}
This may be another solution, without much code in didSelectRowAtIndexPath method. Note that while it may look cleaner, and we do not need an extra variable valueToPass, it may not be a best practice, because the sender argument inside performSegue method is supposed to be the actual object that initiated the segue (or nil).
// 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]
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With