我正在使用配置文件注册视图控制器,当用户从UIPickerController中选择城市时,我想更新UIButton的标题。用户选择城市后,按钮的标题不会更新。
我尝试使用DispatchQueue.main.async,但效果不佳,我在从显示城市选择器的位置关闭视图后尝试更新didSet。当我运行代码时,该值会给出正确的标题,但不会从我的视图中更新和重新加载数据。
第一视图
import UIKit
import Firebase
class PersonalInfoController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
//MARK: Variables
var finalCity: String? {
didSet {
guard let userCity = self.finalCity else { return }
print(cityPicker.currentTitle)
self.cityPicker.setTitle(userCity, for: .normal)
print(cityPicker.currentTitle)
}
}
let cityPicker: UIButton = {
let button = UIButton(type: .system)
button.setTitle("City", for: .normal)
button.backgroundColor = UIColor.rgb(red: 248, green: 101, blue: 46)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 17)
button.setTitleColor(UIColor.white, for: .normal)
button.layer.cornerRadius = 20
button.clipsToBounds = true
button.addTarget(self, action: #selector(handlePickCity), for: .touchUpInside)
return button
}()
//MARK: ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.rgb(red: 235, green: 235, blue: 228)
navigationController?.isNavigationBarHidden = true
setupSubViews()
stackView()
}
@objc func handlePickCity() {
let selectVC = UINavigationController(rootViewController: SelectCity())
selectVC.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
present(selectVC, animated: true, completion: nil)
}
第二视图(选择器显示)
import UIKit
class SelectCity: UIViewController {
//MARK: Variables
let cities = ["Chico", "Orland"]
let picker = CityPicker()
var selectedCity: String?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black.withAlphaComponent(0.7)
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(handleDone))
picker.delegate = self
picker.dataSource = self
view.addSubview(picker)
picker.anchor(top: nil, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
}
//MARK: Action Handler
@objc func handleDone(){
let userInfoVC = PersonalInfoController()
userInfoVC.finalCity = selectedCity
self.dismiss(animated: true, completion: nil)
}
}
extension SelectCity: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return cities.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return cities[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedCity = cities[row]
}
}
我的控制台正在前后打印currentTitle。 这是控制台:
这是用户从选择器中选择城市后的当前状态 可选(“城市”)
这是在用户选择城市Optional(“ Orland”)
之后
答案 0 :(得分:1)
问题是您的cityPicker每次都在创建按钮的新实例。
您可以
var cityPicker: UIButton = UIButton()
创建一个将返回UIButton的方法。
func getButton() -> UIButton {
let button = UIButton(type: .system)
button.setTitle("City", for: .normal)
button.backgroundColor = UIColor.rgb(red: 248, green: 101, blue: 46)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 17)
button.setTitleColor(UIColor.white, for: .normal)
button.layer.cornerRadius = 20
button.clipsToBounds = true
button.addTarget(self, action: #selector(handlePickCity), for: .touchUpInside)
return button
}
cityPicker = getButton()
然后您可以设置标题
cityPicker.setTitle(userCity, for: .normal)
答案 1 :(得分:1)
您的问题出在以下方法中,您在其中创建新的控制器并将selectedCity
字符串分配给新实例。这样就不会更新您现有的PersonalInfoController
。
//MARK: Action Handler
@objc func handleDone(){
let userInfoVC = PersonalInfoController() //New PersonalInfoController is creating and existing controller won't be updated.
userInfoVC.finalCity = selectedCity
self.dismiss(animated: true, completion: nil)
}
因此,您可能必须遵循某些Delegate
模式才能在ViewController之间发送数据。
示例:
protocol SelectCityDelegate {
func didSelectCity(_ city:String)
}
class PersonalInfoController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, SelectCityDelegate {
//////
@objc func handlePickCity() {
let selectCityController = SelectCity()
selectCityController.delegate = self
let selectVC = UINavigationController(rootViewController: selectCityController)
selectVC.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
present(selectVC, animated: true, completion: nil)
}
func didSelectCity(_ city: String) {
finalCity = city
}
//////
}
class SelectCity: UIViewController {
/////
weak var delegate:SelectCityDelegate?
//MARK: Action Handler
@objc func handleDone(){
delegate?.didSelectCity(selectedCity)
self.dismiss(animated: true, completion: nil)
}
/////
}
但是我建议您在PersonalInfoController
内实施“城市选择器”视图,而不是仅为选择器创建新的控制器。