I'm trying to show the details of a promotional coupon with information that comes from a TableViewCel into a View Controller by Performing a Segue.
this is my code in the cellForRowAt indexPath method and also de Perform Segue Function:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let coupons = [couponImage1, couponImage2, couponImage3, couponImage4, couponImage5, couponImage6, couponImage7, couponImage8, couponImage9, couponImage10]
let couponsTitle = [couponTitle1, couponTitle2, couponTitle3, couponTitle4, couponTitle5, couponTitle6, couponTitle7, couponTitle8, couponTitle9, couponTitle10]
let couponsDescription = [couponDesc1, couponDesc2, couponDesc3, couponDesc4, couponDesc5, couponDesc6, couponDesc7, couponDesc8, couponDesc9, couponDesc10]
let couponsCategory = [couponCat1, couponCat2, couponCat3, couponCat4, couponCat5, couponCat6, couponCat7, couponCat8, couponCat9, couponCat10]
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HomeTableViewCell
cell.couponImg.image = coupons[indexPath.row]
cell.couponTitle.text = couponsTitle[indexPath.row]
cell.couponDescription.text = couponsDescription[indexPath.row]
cell.couponCategory.text = couponsCategory[indexPath.row]
if indexPath.row == 0 {
self.sendCouponImg = couponImage1
self.sendCouponTitle = couponTitle1
self.sendCouponDesc = couponDesc1
self.sendCouponCat = couponCat1
} else if indexPath.row == 1 {
self.sendCouponImg = couponImage2
self.sendCouponTitle = couponTitle2
self.sendCouponDesc = couponDesc2
self.sendCouponCat = couponCat2
} else if indexPath.row == 2 {
self.sendCouponImg = couponImage3
self.sendCouponTitle = couponTitle3
self.sendCouponDesc = couponDesc3
self.sendCouponCat = couponCat3
} else if indexPath.row == 3 {
self.sendCouponImg = couponImage4
self.sendCouponTitle = couponTitle4
self.sendCouponDesc = couponDesc4
self.sendCouponCat = couponCat4
} else if indexPath.row == 4 {
self.sendCouponImg = couponImage5
self.sendCouponTitle = couponTitle5
self.sendCouponDesc = couponDesc5
self.sendCouponCat = couponCat5
} else if indexPath.row == 5 {
self.sendCouponImg = couponImage6
self.sendCouponTitle = couponTitle6
self.sendCouponDesc = couponDesc6
self.sendCouponCat = couponCat6
} else if indexPath.row == 6 {
self.sendCouponImg = couponImage7
self.sendCouponTitle = couponTitle7
self.sendCouponDesc = couponDesc7
self.sendCouponCat = couponCat7
} else if indexPath.row == 7 {
self.sendCouponImg = couponImage8
self.sendCouponTitle = couponTitle8
self.sendCouponDesc = couponDesc8
self.sendCouponCat = couponCat8
} else if indexPath.row == 8 {
self.sendCouponImg = couponImage9
self.sendCouponTitle = couponTitle9
self.sendCouponDesc = couponDesc9
self.sendCouponCat = couponCat9
} else if indexPath.row == 9 {
self.sendCouponImg = couponImage10
self.sendCouponTitle = couponTitle10
self.sendCouponDesc = couponDesc10
self.sendCouponCat = couponCat10
}
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "couponsDetails"){
let viewController:DetailCouponsViewController = segue.destination as! DetailCouponsViewController
viewController.getCouponsImage = self.sendCouponImg
viewController.getCouponsTitle = self.sendCouponTitle
viewController.getCouponsDescription = self.sendCouponDesc
viewController.getCouponsCategory = self.sendCouponCat
}
}
And this is the code at the Second View Controller:
class DetailCouponsViewController: UIViewController {
@IBOutlet weak var couponCategory: UILabel!
@IBOutlet weak var couponTitle: UILabel!
@IBOutlet weak var couponImage: UIImageView!
@IBOutlet weak var couponDescription: UITextView!
@IBOutlet weak var couponLongDescription: UITextView!
@IBOutlet var starButtons: [UIButton]!
var getCouponsTitle : String = ""
var getCouponsDescription : String = ""
var getCouponsCategory : String = ""
var getCouponsImage : UIImage? = nil
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(false)
self.couponCategory.text = getCouponsCategory
self.couponDescription.text = getCouponsDescription
self.couponLongDescription.text = getCouponsDescription
self.couponTitle.text = getCouponsTitle
self.couponImage.image = getCouponsImage
}
My issue is that the data appearing on the Details View Controller is not the correct one, when I click the first row on the HomewTableViewCell is throwing the values that comes at the third row, and it's all mixed up. Does anyone can tell me what am I doing wrong please?
cellForRowAt
function's purpose is to create a cell object which is a view, configure it and then display them. When you scroll down, this method is called so that the next cell will be prepared and then displayed. So if you set your variables in this function like that, the values in these variables are from the last cell that the tableView is prepared for display.
For example, table view has 10 rows with variable foo values from 0 to 9. Your screen can display only 3 cells. When your view is loaded, your table view will call cellForRow
three times to prepare views for cell 0 1 and 2 to be displayed. Since cell 2 is processed in the end, from your code, your local variable will have value 2. Then when you click on the first cell, you passed value 2 into the next view controller.
To make it right, with the purpose of this function, first you need to move the definition of the array outside because you don't want to recreate then every time when a cell is prepared. Plus you will also need to access the arrays from another function when the cell is clicked. Given that your array data comes from a http request, first create variables outside to be empty arrays.
var coupons: [String] = []
var couponsTitle: [String] = []
var couponsDescription: [String] = []
var couponsCategory: [String] = []
Then in your HTTP callback, add value to these arrays and then call tableView.reloadData() to reload the table with data from the server
func yourHTTPCallBack() {
//coupons = [foo1, foo2 ...]
tableView.reloadData()
}
In your cellForRow
, you are only displaying the cell, instead of saving any value to the local variables. Because click hasn't happened yet!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HomeTableViewCell
cell.couponImg.image = coupons[indexPath.row]
cell.couponTitle.text = couponsTitle[indexPath.row]
cell.couponDescription.text = couponsDescription[indexPath.row]
cell.couponCategory.text = couponsCategory[indexPath.row]
return cell
}
Then say you want to trigger segue when clicked on a cell, use this function from table view delegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.sendCouponImg = coupons[indexPath.row]
self.sendCouponTitle = couponsTitle[indexPath.row]
self.sendCouponDesc = couponsDescription[indexPath.row]
self.sendCouponCat = couponsCategory[indexPath.row]
//Do your segue here
}