Swift中Eureka列表选择:选中最后一项返回后自动取消选中问题
Fixing the Unselected Korean Language Issue in Eureka Form
Hey there! Let's figure out why your Korean language selection keeps getting unselected when you leave the view controller, and fix this properly without that temporary hardcode in viewWillAppear.
Let's Break Down the Problems in Your Code
Incorrect row setup in
viewDidLoad- You’re calling
form.setValues([language : language])inside the loop for every language option. This overwrites the form’s selection state every time the loop runs, so only the last iteration’s setting sticks (and it’s not even the right way to set row selection). - You’re hardcoding
lrow.value = nilfor every row, which means none of them start selected even if there’s a saved value in UserDefaults.
- You’re calling
Limited
viewWillAppearlogic- Your current code only handles the Korean language case, so other saved languages won’t restore correctly. Plus, it doesn’t check if there’s actually a saved value before forcing the selection.
Redundant saving in
viewDidAppear- You’re saving
languageSelectedagain here, but you already do this invalueHasBeenChanged. This can lead to inconsistent state if the two values ever get out of sync.
- You’re saving
Here's the Fixed Code
import Eureka class ListSectionsController: FormViewController { let defaults = UserDefaults.standard var languageSelected = "English (default)" override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Restore the saved language selection correctly for all options if let savedLanguage = defaults.string(forKey: "LanguageSelection") { languageSelected = savedLanguage // Update the form to reflect the saved selection if let section = form.first as? SelectableSection<ImageCheckRow<String>> { section.selectedRow()?.deselect() // Deselect any currently selected row if let rowToSelect = section.rows.first(where: { $0.selectableValue == savedLanguage }) { rowToSelect.select() } } } else { // If no saved value, default to English languageSelected = "English (default)" if let section = form.first as? SelectableSection<ImageCheckRow<String>> { section.selectedRow()?.deselect() if let rowToSelect = section.rows.first(where: { $0.selectableValue == languageSelected }) { rowToSelect.select() } } } } override func viewDidLoad() { super.viewDidLoad() let languageSelections = ["English (default)", "Spanish", "Japanese 日本語", "Chinese Mandarin 普通话", "Indonesian", "Dutch - het Nederlands", "Korean 한국어"] // Get saved language once, before setting up rows let savedLanguage = defaults.string(forKey: "LanguageSelection") ?? languageSelected form +++ SelectableSection<ImageCheckRow<String>>() { section in section.header = HeaderFooterView(title: "Language Selection") section.onSelectSelectableRow = { _, selectedRow in // Optional: Auto-deselect other rows (Eureka does this by default for single-select, but explicit is safe) selectedRow.section?.rows.forEach { row in if row !== selectedRow { row.deselect() } } } } for option in languageSelections { form.last! <<< ImageCheckRow<String>(option) { lrow in lrow.title = option lrow.selectableValue = option // Set row's selected state based on saved value lrow.value = option == savedLanguage ? option : nil } } } override func valueHasBeenChanged(for row: BaseRow, oldValue: Any?, newValue: Any?) { guard let section = row.section as? SelectableSection<ImageCheckRow<String>>, section === form[0], let selectedValue = section.selectedRow()?.baseValue as? String else { return } print("Selected: \(selectedValue)") languageSelected = selectedValue defaults.set(languageSelected, forKey: "LanguageSelection") } // Remove the redundant viewDidAppear save // override func viewDidAppear(_ animated: Bool) { // defaults.set(languageSelected, forKey: "LanguageSelection") // } }
Key Changes Explained
Proper row initialization in
viewDidLoad- We fetch the saved language once before building the rows, then set each row’s
valueto match whether it’s the saved option. This ensures the correct row starts selected when the view loads. - Removed the loop-internal
form.setValuescalls, which were causing unexpected overwrites.
- We fetch the saved language once before building the rows, then set each row’s
Robust
viewWillAppearrestoration- Now handles all language options, not just Korean. It deselects any existing selection first, then finds and selects the saved language row. If there’s no saved value, it defaults to English correctly.
Removed redundant save
- Got rid of the
viewDidAppearsave sincevalueHasBeenChangedalready saves the selection when the user picks an option. This prevents conflicting saves.
- Got rid of the
Explicit single-select handling
- Added
onSelectSelectableRowto the section to ensure only one row is selected at a time (Eureka’s default forSelectableSection, but making it explicit helps avoid edge cases).
- Added
Test It Out
Now when you select Korean (or any other language) and navigate away, come back to the view controller—your selection should stay intact. No more random unselection, and the logic works for all options without hardcoding!
内容的提问来源于stack exchange,提问作者grm
相关产品推荐
相关产品推荐

