Reputation: 21
*hi I have a problem if anyone can guide me to the appropriate solution for this one it will be awesome.... I have a tableview with list items that can be selected (like a checkbox) also a textview that when I write there I don't won't the text deleted (for the user) every time It scrolls. my custom cell class - >
class ReportIssueTableViewCell: UITableViewCell, ReusableView, NibLoadableView {
//MARK: Properties
@IBOutlet private weak var lblTitleIssue: UILabel!
@IBOutlet private weak var imgCircleCheck: UIImageView!
@IBOutlet private weak var textView: WSTextView!
@IBOutlet private weak var stackView: UIStackView!
@IBOutlet private weak var sepratorView: UIView!
private var reportIssue: ReportIssue?
private var textContent = ""
private var lastIndex = false
//MARK: Methods
func setupDataForCell(isSelected: Bool, reportIssues: ReportIssue, lastIndex: Bool) {
self.isSelected = isSelected
self.reportIssue = reportIssues
self.lastIndex = lastIndex
updateUI()
}
override func prepareForReuse() {
super.prepareForReuse()
textView.text = textContent
imgCircleCheck.image = nil
}
func updateUI() {
guard let reportIssue = reportIssue else { return }
lblTitleIssue.text = reportIssue.name
updateImageUI()
updateTextView()
updateTitleUI()
}
func sepratorView(hide: Bool, lastIndex: Bool) {
sepratorView.isHidden = (lastIndex && hide)
}
//MARK: Private Methods
private func updateTitleUI() {
let font = lblTitleIssue.font.pointSize
lblTitleIssue.font = isSelected ? SharedFonts.latoBold.ofSize(font) : SharedFonts.latoRegular.ofSize(font)
}
private func updateImageUI() {
imgCircleCheck.image = isSelected ? R.image.iconCircleCheckFull() : SharedAssets.iconsCircle()
}
private func updateTextView() {
textView.isHidden = !(lastIndex && isSelected)
}
}
also my view controller class and the tableview delegate & data source...
extension ReportIssueViewController: UITableViewDelegate , UITableViewDataSource {
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if section == 0 {
let footerView = UIView()
footerView.backgroundColor = SharedColors.woodspoon_extra_light_gray()
return footerView
}else {
return UIView()
}
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 8
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let name = viewModel.reportTopics?[section].name else { return nil }
let header = SectionTitleHeaderView(textDescriptor: .init(text: name, appearance: .init(color: SharedColors.woodspoon_black(), font: SharedFonts.latoBlack.ofSize(18))))
return header
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
} else {
//Fallback on earlier versions
}
return UITableView.automaticDimension
}
func numberOfSections(in tableView: UITableView) -> Int {
return viewModel.reportTopics?.count ?? 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.reportTopics?[section].reportIssues?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: ReportIssueTableViewCell = tableView.dequeueReusableCell(for: indexPath)
if let issue = viewModel.reportTopics?[indexPath.section].reportIssues?[indexPath.row] {
let countIssues = viewModel.reportTopics?[indexPath.section].reportIssues?.count ?? 0
let lastIssue = countIssues - 1 == indexPath.row
let isSelected = tableView.indexPathsForSelectedRows?.contains(where: { $0.section == indexPath.section && $0.row == indexPath.row })
//remove seperator from last cell in each section
if isSelected == isSelected {
cell.sepratorView(hide: true ,lastIndex: lastIssue)
}
cell.setupDataForCell(isSelected: isSelected ?? false, reportIssues: issue, lastIndex: lastIssue)
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
cellPressed(indexPath: indexPath)
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
cellPressed(indexPath: indexPath)
}
private func cellPressed(indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? ReportIssueTableViewCell else { return }
tableView.beginUpdates()
cell.updateUI()
tableView.endUpdates()
}*
Upvotes: 1
Views: 987
Reputation: 131
I think it happens because the reuse of cells.
Your problem starts here:
isSelected = tableView.indexPathsForSelectedRows?.contains(where: {
$0.section == indexPath.section && $0.row == indexPath.row
})
Add an isSelected value to the model used to populate the cell and get it from your viewModel by adding an isSelected func that return bool value and get it inside cellForRowAt IndexPath.
Something like this:
func isSelected(by indexPath: IndexPath) { }
And remember to update the model (via viewModel) when a cell was selected.
Upvotes: 1