I am fairly new to Swift and have researched the following problem extensively yet unsuccessfully.
I've created a custom TableViewCell class named ConversationCell
and defined its UI in a NIB/XIB file.
import UIKit
import SwipeCellKit
class ConversationCell: SwipeTableViewCell {
@IBOutlet weak var distanceLabel: UILabel!
@IBOutlet weak var locationLabel: UILabel!
@IBOutlet weak var subjectLabel: UILabel!
@IBOutlet weak var bodyLabel: UILabel!
@IBOutlet weak var profileImageView: UIImageView!
@IBOutlet weak var usernameLabel: UILabel!
@IBOutlet weak var starImageView: UIImageView!
@IBOutlet weak var dateLabel: UILabel!
var isFollowed = false
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
Then I wrote a simple class named Conversation
that is the model class for ConversationCell
.
class Conversation {
var distance = "123 ft."
var location = "123 Market St"
var date = "Yesterday, 10:45AM"
var subject = "Default subject."
var body = "Default body"
// var subject = "My Subject"
//var body = "My Body"
var username = "worldsurfer"
var profilePhoto = UIImage(named: "profilePhoto")
}
Finally, I added a TableView
that uses the custom ConversationCell
to my class HomeTabViewController
, which is a ViewController acting as both the source and delegate for the TableView.
Please take a look at the code below where I print the content of the labels in the cell within func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
.
Instead of returning the label values that I've defined when initializing my conversation array (i.e., "1st Conversation", "2nd Conversation", "3rd Conversation" - which get properly displayed in the TableView at runtime), it returns the default label text values that are defined in the NIB file (i.e., "The spectable before us was indeed sublime.").
import UIKit
import SwipeCellKit
class HomeTabViewController: CoreDesignViewController {
@IBOutlet weak var tableView: UITableView!
var conversationArray : [Conversation] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "ConversationCell", bundle: nil), forCellReuseIdentifier: "homeTabCell")
tableView.dataSource = self
tableView.delegate = self
let conversation1 = Conversation()
conversation1.subject = "1st conversation"
conversationArray.append(conversation1)
let conversation2 = Conversation()
conversation2.subject = "2nd Conversation"
conversationArray.append(conversation2)
let conversation3 = Conversation()
conversation3.subject = "3rd conversation"
conversationArray.append(conversation3)
tableView.estimatedRowHeight = tableView.rowHeight
tableView.rowHeight = UITableViewAutomaticDimension
self.showNavBar()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension HomeTabViewController: UITableViewDataSource, UITableViewDelegate, SwipeTableViewCellDelegate{
//MARK: - UITableViewDataSource Protocol Implementation
/***************************************************************/
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return conversationArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "homeTabCell", for: indexPath) as? ConversationCell
else{
fatalError("The dequeued cell is not an instance of homeTabCell.")
}
//To make the cell Swipeable via SwipeCellKit
cell.delegate = self
print("CELL_FOR_ROW_AT - indexPath.row = \(indexPath.row) | Conversation.subject = \(conversationArray[indexPath.row].subject)")
//Initializing the cell
cell.distanceLabel.text = conversationArray[indexPath.row].distance
cell.locationLabel.text = conversationArray[indexPath.row].location
cell.dateLabel.text = conversationArray[indexPath.row].date
cell.subjectLabel.text = conversationArray[indexPath.row].subject
cell.bodyLabel.text = conversationArray[indexPath.row].body
cell.usernameLabel.text = conversationArray[indexPath.row].username
cell.profileImageView.image = conversationArray[indexPath.row].profilePhoto
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "homeTabCell", for: indexPath) as? ConversationCell
else{
fatalError("The dequeued cell is not an instance of homeTabCell.")
}
print("DID_SELECT_ROW_AT - Selected Row = \(indexPath.row) | cell.subjectLabel.text = \(cell.subjectLabel.text!)")
}
I've tried with all the different labels in the custom cell and same result: it always prints out the corresponding default text values of the XIB file.
Any idea why (the hell) this is happening? :) Thanks much!
Look what you are doing in didSelectRowAt
!
guard let cell = tableView.dequeueReusableCell(withIdentifier: "homeTabCell", for: indexPath) as? ConversationCell
else{
fatalError("The dequeued cell is not an instance of homeTabCell.")
}
You are dequeuing a new cell! The cell returned from dequeueReusableCell
is always the same as the one you designed in the XIB file.
Instead of dequeuing a new cell, you should get the cell in the table view that corresponds to the index path:
let cell = tableView.cellForRow(at: indexPath)
// print cell contents...
Or just access the array that you've got:
let conversation = conversationArray[indexPath.row]
// print conversation's properties...