Wazza
Wazza

Reputation: 1885

Add and remove view on cell selection

I have a tableview that displays some data in each cell, when the cell is selected it should expand and display more data. I have the basics of the code in but when the cell is selected the data doesn't show until another cell is selected. And the data seems to be duplicating itself into the other cells when selected. I'm sure I just need to move the calling of methods around and despite think I've tried all the combinations I can't find a solution. Heres the code that i think matters:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let answers = questions[indexPath.row].answers?.allObjects as! [Answer]
    let cell = tableView.cellForRow(at: indexPath as IndexPath) as! CollectedDataTableViewCell

    switch selectedIndexPath {
    case nil:
        cell.contentView.viewWithTag(indexPath.row + 1)?.removeFromSuperview()
        selectedIndexPath = indexPath as NSIndexPath?
    default:
        if selectedIndexPath! as IndexPath == indexPath {
            addAnswerViews(cell: cell, answers: answers, index: indexPath.row + 1)
            selectedIndexPath = nil
        } else {
            cell.contentView.viewWithTag(indexPath.row + 1)?.removeFromSuperview()
            selectedIndexPath = indexPath as NSIndexPath?
        }
    }

    tableView.reloadRows(at: [indexPath as IndexPath], with: UITableViewRowAnimation.automatic)

    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}

func addAnswerViews(cell: CollectedDataTableViewCell, answers: [Answer], index: Int) {

    var extra = CGFloat(0)
    var percentage: Double = 0

    let percentFormatter = NumberFormatter()

    percentFormatter.numberStyle = .percent
    percentFormatter.multiplier = 100
    percentFormatter.minimumFractionDigits = 1
    percentFormatter.maximumFractionDigits = 2

    answers.forEach { answer in
        let height = self.height - 6
        let width = cell.contentView.frame.width
        let view = UIView(frame: CGRect(x: 0, y: height + extra, width: width, height: height))
        view.tag = index

        let answerLabel = UILabel(frame: CGRect(x: 15, y: 0, width: width - 30, height: height/2))
        answerLabel.backgroundColor = .clear
        answerLabel.adjustsFontSizeToFitWidth = true
        answerLabel.text = answer.text

        if answer.timesSelected == 0 || answer.timesSelectedCorrectly == 0 {

            percentage = 0
        } else {

            percentage = Double(answer.timesSelectedCorrectly)/Double(answer.timesSelected)
        }

        var percentString = percentFormatter.string(from: NSNumber(value: percentage))
        if percentage == 1.0 { percentString = "100%"}
        if percentage == 0.0 { percentString = "0%" }

        let timesSelectedCorrectlyLabel = UILabel(frame: CGRect(x: 15, y: height/2, width: width/2 - 15, height: height/2))
        timesSelectedCorrectlyLabel.backgroundColor = .clear
        timesSelectedCorrectlyLabel.adjustsFontSizeToFitWidth = true
        timesSelectedCorrectlyLabel.text = "Times selected correctly: \(answer.timesSelectedCorrectly) - \(percentString!)"

        let timesSelectedLabel = UILabel(frame: CGRect(x: width/2 - 15, y: height/2, width: width/2 - 15, height: height/2))
        timesSelectedLabel.backgroundColor = .clear
        timesSelectedLabel.adjustsFontSizeToFitWidth = true
        timesSelectedLabel.text = "Times selected: \(answer.timesSelected)"

        view.addSubview(answerLabel)
        view.addSubview(timesSelectedCorrectlyLabel)
        view.addSubview(timesSelectedLabel)

        cell.contentView.addSubview(view)
        extra += height
    }
}

Upvotes: 0

Views: 64

Answers (1)

Sandeep Bhandari
Sandeep Bhandari

Reputation: 20379

Modify your didselectRowAtIndexPath as below :)

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let answers = questions[indexPath.row].answers?.allObjects as! [Answer]
    let cell = tableView.cellForRow(at: indexPath as IndexPath) as! CollectedDataTableViewCell

    if self.previouslySelectedIndexPath != nil {
        cell.contentView.viewWithTag(previouslySelectedIndexPath.row + 1)?.removeFromSuperview()
    }
    addAnswerViews(cell: cell, answers: answers, index: indexPath.row + 1)

    if self.previouslySelectedIndexPath != nil {
       tableView.reloadRows(at: [indexPath,self.previouslySelectedIndexPath], with: UITableViewRowAnimation.automatic)
    }
    else {
       tableView.reloadRows(at: [indexPath as IndexPath], with: UITableViewRowAnimation.automatic)
    }
    self.previouslySelectedIndexPath = indexPath
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}

Upvotes: 2

Related Questions