S.MacPherson
S.MacPherson

Reputation: 75

Custom Cell in TableView hide label on DidSelect

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

Answers (4)

vadian
vadian

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

deepak
deepak

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

Alladinian
Alladinian

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

emrcftci
emrcftci

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

Related Questions