I am trying to show the default selected cell with a different button image. But could not show it when I show the languages page. I am trying to check if it is selected or not. If selected call setupSelected and if not selected call setup function.
But when I chose language I always see my tableview with no selection after all. setSelected works well and the image of the selected cells is changing.
Language
enum Language: String, CaseIterable {
case tr = "tr"
case eng = "en"
case az = "az"
var title: String {
switch self {
case .tr: return "settings.language.turkish".localized
case .eng: return "settings.language.english".localized
case .az: return "settings.language.azerbeijan".localized
}
}
var code: String {
switch self {
case .tr: return "tr"
case .eng: return "en"
case .az: return "az-AZ"
}
}
}
My viewModel
final class LanguageViewModel {
var locales: [Language] = [.tr, .eng, .az] //.ar
var currentLanguage = UserDefaultsUtil.getDeviceLanguage()
var languages: [LanguageModel] = []
func getLanguageTitles() {
languages = [
LanguageModel(language: .tr, isSelected: currentLanguage == locales[0].code ? true : false),
LanguageModel(language: .eng, isSelected: currentLanguage == locales[1].code ? true : false),
LanguageModel(language: .az, isSelected: currentLanguage == locales[2].code ? true : false)
]
}
}
My model
struct LanguageModel {
let language: Language
var isSelected: Bool
}
My ViewController
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return languageCell(indexPath: indexPath)
}
private func languageCell(indexPath: IndexPath) -> LanguageTableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: LanguageTableViewCell.identifier, for: indexPath) as! LanguageTableViewCell
if cell.isSelected {
cell.setupSelected(languageTitles[indexPath.row])
return cell
} else {
cell.setup(languageTitles[indexPath.row])
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: LanguageTableViewCell.identifier, for: indexPath) as! LanguageTableViewCell
tableView.deselectRow(at: indexPath, animated: true)
let item = languageTitles[indexPath.row]
cell.setupSelected(item)
tableView.reloadData()
}
My cell
@IBOutlet weak var empty: UIImageView!
@IBOutlet weak var title: UILabel!
var currentLanguage = UserDefaultsUtil.getDeviceLanguage()
static let identifier = String(describing: LanguageTableViewCell.self)
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func setup(_ languageTitles: LanguageModel) {
title.label(textStr: languageTitles.language.rawValue, textColor: KSColor.neutral700.getColor(), textFont: UIFont.sfProTextMedium(size: 15), fontSize: 15, lineSpacing: -0.16, paragraphStyle: NSMutableParagraphStyle())
}
func setupSelected(_ languageTitles: LanguageModel) {
setSelected(true, animated: true)
title.label(textStr: languageTitles.language.rawValue, textColor: KSColor.neutral700.getColor(), textFont: UIFont.sfProTextMedium(size: 15), fontSize: 15, lineSpacing: -0.16, paragraphStyle: NSMutableParagraphStyle())
self.empty.image = UIImage(named: "icon_done_bold")
self.empty.makeRounded()
self.empty.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
self.empty.setImageColor(color: KSColor.neutral100.getColor())
self.empty.backgroundColor = KSColor.ocean500Base.getColor()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
self.empty.image = UIImage(named: "icon_done_bold")
self.empty.makeRounded()
self.empty.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
self.empty.setImageColor(color: KSColor.neutral100.getColor())
self.empty.backgroundColor = KSColor.ocean500Base.getColor()
} else {
self.empty.transform = CGAffineTransform(scaleX: 1, y: 1)
self.empty.image = UIImage(named: "icon_radio_unselected")
self.empty.setImageColor(color: KSColor.neutral100.getColor())
self.empty.backgroundColor = .white
}
}
}extension LanguageTableViewCell: Reusable, NibLoadable { }
this is how I see my tableview. In fact, tr is selected.
CodePudding user response:
You need
1- First remove ? :
it will give same result
LanguageModel(language: .tr, isSelected: currentLanguage == locales[0].code),
LanguageModel(language: .eng, isSelected: currentLanguage == locales[1].code),
LanguageModel(language: .az, isSelected: currentLanguage == locales[2].code)
2- Don't depend on cell's isSelected
property as cells are dequeued when you scroll ,so using it will give you wrong states so instead of
if cell.isSelected {
cell.setupSelected(languageTitles[indexPath.row])
return cell
} else {
cell.setup(languageTitles[indexPath.row])
return cell
}
Do
let item = languageTitles[indexPath.row]
if item.isSelected {
cell.setupSelected(item)
return cell
} else {
cell.setup(item)
return cell
}
3- Remove override func setSelected(
and move its implementation inside table didSelectRowAt
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = languageTitles[indexPath.row]
let value = item.isSelected
// Edit isSelected property and refresh table
languageTitles.forEach { $0.isSelected = false }
item.isSelected = !value
tableView.reloadData()
}