Home > Net >  Show Selected Item Cell At First Appearance
Show Selected Item Cell At First Appearance

Time:03-29

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.

enter image description here

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()

}
  • Related