Swift 每次我在 tableView 中滚动时,被选中的单元格都被取消选中
Swift Every time I scroll in tableView the cells that been selected are getting unselected
*嗨,我有一个问题,如果有人能指导我找到合适的解决方案,那就太棒了....
我有一个 tableview,其中包含可以选择的列表项(如复选框)还有一个 textview,当我在那里写时,我不会在每次滚动时删除(为用户)文本。
我的自定义单元格 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)
}
}
还有我的视图控制器 class 和表视图委托和数据源...
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: { [=12=].section == indexPath.section && [=12=].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()
}*
我认为这是因为细胞的重复使用。
您的问题从这里开始:
isSelected = tableView.indexPathsForSelectedRows?.contains(where: {
[=10=].section == indexPath.section && [=10=].row == indexPath.row
})
向用于填充单元格的模型添加一个 isSelected 值,并通过添加一个 return bool 值的 isSelected 函数从您的 viewModel 中获取它,并在 cellForRowAt IndexPath 中获取它。
像这样:
func isSelected(by indexPath: IndexPath) { }
并记得在选择单元格时更新模型(通过 viewModel)。
*嗨,我有一个问题,如果有人能指导我找到合适的解决方案,那就太棒了.... 我有一个 tableview,其中包含可以选择的列表项(如复选框)还有一个 textview,当我在那里写时,我不会在每次滚动时删除(为用户)文本。 我的自定义单元格 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)
}
}
还有我的视图控制器 class 和表视图委托和数据源...
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: { [=12=].section == indexPath.section && [=12=].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()
}*
我认为这是因为细胞的重复使用。
您的问题从这里开始:
isSelected = tableView.indexPathsForSelectedRows?.contains(where: {
[=10=].section == indexPath.section && [=10=].row == indexPath.row
})
向用于填充单元格的模型添加一个 isSelected 值,并通过添加一个 return bool 值的 isSelected 函数从您的 viewModel 中获取它,并在 cellForRowAt IndexPath 中获取它。
像这样:
func isSelected(by indexPath: IndexPath) { }
并记得在选择单元格时更新模型(通过 viewModel)。