视图加载后TextField数据丢失:城市选择触发异常覆盖国家值
嘿,我看你遇到了两个挺典型的iOS页面跳转传值问题,咱们一步步来解决:
问题1:点击城市输入框唤起了错误的国家选择器
这个问题十有八九是Storyboard里的Segue关联错了,或者代码触发Segue时用错了标识符。你可以从这两方面排查:
- 打开Storyboard,检查
cityTextFeild的点击触发事件(比如通过Touch Up Inside或者Segue直接关联)是不是连到了citySelectorView,而不是countrySelectorView; - 如果是用代码触发Segue(比如在
UITextFieldDelegate的textFieldDidBeginEditing方法里),确认调用performSegue(withIdentifier:)时的标识符是对应城市选择器的,别和国家的搞混。
举个代码触发的正确示例:
func textFieldDidBeginEditing(_ textField: UITextField) { textField.resignFirstResponder() // 先收起键盘 if textField == countryTextFeild { performSegue(withIdentifier: "GoToCountrySelector", sender: self) } else if textField == cityTextFeild { performSegue(withIdentifier: "GoToCitySelector", sender: self) } }
记得在Storyboard里给两个Segue分别设置好对应的ID(比如上面的GoToCountrySelector和GoToCitySelector),别搞反了。
问题2:返回后原国家输入框内容被清空
这个问题出在传值时没保留原有数据。你看adminSignUp的viewDidLoad是靠countryValue和cityValue来设置输入框文本的,但从citySelectorView返回时,只传了cityValue,没把原来的countryValue带回去,导致新的adminSignUp实例里countryValue为nil,输入框自然就被清空了。
解决办法很简单:在两个选择器的prepare(for:sender:)方法里,同时传递当前已有的所有值。
第一步:给选择器添加接收原有数据的属性
在countrySelectorView和citySelectorView里各加两个属性:
// 在CountrySelectorView里 var existingCountry: String? var existingCity: String? // 在CitySelectorView里 var existingCountry: String? var existingCity: String?
第二步:跳转选择器时传递原有数据
在adminSignUp的prepare(for:sender:)里,把当前输入框的内容传给选择器:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let countrySelector = segue.destination as? countrySelectorView { countrySelector.existingCountry = countryTextFeild.text countrySelector.existingCity = cityTextFeild.text } else if let citySelector = segue.destination as? citySelectorView { citySelector.existingCountry = countryTextFeild.text citySelector.existingCity = cityTextFeild.text } }
第三步:返回时带回所有数据
修改两个选择器的prepare(for:sender:):
// CountrySelectorView的prepare方法 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let adminVC = segue.destination as? adminSignUp else { return } adminVC.countryValue = countryValue ?? existingCountry // 优先用选中的新值,没有就用原有值 adminVC.cityValue = existingCity // 保留原有城市值 } // CitySelectorView的prepare方法 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let adminVC = segue.destination as? adminSignUp else { return } adminVC.cityValue = cityValue ?? existingCity adminVC.countryValue = existingCountry // 保留原有国家值 }
这样不管从哪个选择器返回,另一个输入框的内容都不会被清空啦。
另外提个小建议:Swift里类名要遵循大驼峰命名法,比如把adminSignUp改成AdminSignUp,countrySelectorView改成CountrySelectorView,代码会更规范哦~
内容的提问来源于stack exchange,提问作者Qureshi A Jasham

