Reputation: 1885
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
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