Reputation: 75
I can't seem to figure out what I'm doing wrong.
I have a custom cell which has its own UITableViewCell
and nib (3 labels).
If I select the cell I want to show/hide the Resolved Label. I can't seem to change the ResolvedLabel to Hidden or Show. The function gets called as I can see the Print Statement.
Code in didSelectRowAt
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! ResolvedIssueTableViewCell
if cell.resolvedLabel.isHidden == true {
tableView.deselectRow(at: indexPath, animated: true)
print("THIS HAS BEEN SELECTED RESOLVED")
cell.resolvedLabel.isHidden = false
self.resolvedIssueType.append(self.issues[indexPath.row].partType)
self.resolvedIssues.append(self.issues[indexPath.row].documentId)
print(self.resolvedIssues)
} else if cell.resolvedLabel.isHidden == false {
tableView.deselectRow(at: indexPath, animated: true)
print("THIS HAS BEEN SELECTED NOT RESOLVED")
cell.resolvedLabel.isHidden = true
if let index = self.resolvedIssues.firstIndex(of:self.issues[indexPath.row].documentId) {
self.resolvedIssues.remove(at: index)
self.resolvedIssueType.remove(at: index)
}
print(self.resolvedIssues)
print(self.resolvedIssueType)
}
}
Upvotes: 0
Views: 1165
Reputation: 285150
As always, keep all information about one row in the data model rather than using separate arrays. In didSelectRowAt
modify the model and reload the row. This is the most reliable and efficient way.
In the data model add a property
var isResolved = false
in cellForRow
set the hidden
property of the text field depending on isResolved
.
let issue = self.issues[indexPath.row]
cell.resolvedLabel.isHidden = issue.isResolved
Replace didSelectRowAt
with (yes, the 3 lines are sufficient)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
self.issues[indexPath.row].isResolved.toggle()
tableView.reloadRows(at: [indexPath], with: .none)
}
and delete the two extra arrays.
To get all resolved items just filter
the array
let resolvedIssues = self.issues.filter{ $0.isResolved }
Upvotes: 0
Reputation: 78
After select row. call tableview.reloaddata() function.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! ResolvedIssueTableViewCell
if cell.resolvedLabel.isHidden == true {
tableView.deselectRow(at: indexPath, animated: true)
print("THIS HAS BEEN SELECTED RESOLVED")
cell.resolvedLabel.isHidden = false
self.resolvedIssueType.append(self.issues[indexPath.row].partType)
self.resolvedIssues.append(self.issues[indexPath.row].documentId)
print(self.resolvedIssues)
} else if cell.resolvedLabel.isHidden == false {
tableView.deselectRow(at: indexPath, animated: true)
print("THIS HAS BEEN SELECTED NOT RESOLVED")
cell.resolvedLabel.isHidden = true
if let index = self.resolvedIssues.firstIndex(of:self.issues[indexPath.row].documentId) {
self.resolvedIssues.remove(at: index)
self.resolvedIssueType.remove(at: index)
}
print(self.resolvedIssues)
print(self.resolvedIssueType)
}
tableView.reloadData()
}
Upvotes: 0
Reputation: 35646
Honestly, it doesn't matter why this doesn't work because the whole approach should be different.
Instead of directly trying to manipulate the cell, something that can be problematic for a lot of reasons (the main one being cell reusability), change the model (as you already do) and refresh the tableView - or better yet refresh just the affected cell.
So your code would be something like this (please note that I have no way to test this, so it's from the top of my head, but the genera idea is valid):
1. Make the change in the model
2. Reflect that change in your view (the cell)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
guard let cell = tableView.cellForRow(at: indexPath) as? ResolvedIssueTableViewCell else {
print("Wrong type of cell. Bailing out...")
return
}
let isResolved = ...// Probably by looking into something like `self.resolvedIssues.firstIndex(of:self.issues[indexPath.row].documentId)` judging from your code
if isResolved {
print("THIS HAS BEEN SELECTED RESOLVED")
self.resolvedIssueType.append(self.issues[indexPath.row].partType)
self.resolvedIssues.append(self.issues[indexPath.row].documentId)
print(self.resolvedIssues)
} else {
print("THIS HAS BEEN SELECTED NOT RESOLVED")
if let index = self.resolvedIssues.firstIndex(of:self.issues[indexPath.row].documentId) {
self.resolvedIssues.remove(at: index)
self.resolvedIssueType.remove(at: index)
}
print(self.resolvedIssues)
print(self.resolvedIssueType)
}
tableView.reloadRows(at: [indexPath], with: .automatic)
}
then make the visual state of your cells reflect your model:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = ...
cell.resolvedLabel.isHidden = <whatever_makes_sense>
...
}
Upvotes: 0
Reputation: 3514
You should call tableView.reloadData()
in the end of didSelectRowAt
function.
I've done some refactor your code
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
guard let cell = tableView.cellForRow(at: indexPath) as? ResolvedIssueTableViewCell else { return }
if cell.resolvedLabel.isHidden {
print("THIS HAS BEEN SELECTED RESOLVED")
cell.resolvedLabel.isHidden = false
self.resolvedIssueType.append(self.issues[indexPath.row].partType)
self.resolvedIssues.append(self.issues[indexPath.row].documentId)
print(self.resolvedIssues)
} else {
print("THIS HAS BEEN SELECTED NOT RESOLVED")
cell.resolvedLabel.isHidden = true
if let index = self.resolvedIssues.firstIndex(of:self.issues[indexPath.row].documentId) {
self.resolvedIssues.remove(at: index)
self.resolvedIssueType.remove(at: index)
}
print(self.resolvedIssues)
print(self.resolvedIssueType)
}
tableView.reloadData() // Here is the magic :)
}
You can learn more from Nicholas Swift's Medium Article
Upvotes: 0