【问题标题】:How to update .setTitle for a UIButton using didSet?如何使用 didSet 更新 UIButton 的 .setTitle?
【发布时间】:2018-12-26 07:08:47
【问题描述】:

我正在使用个人资料注册视图控制器,当用户从 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。 这是控制台:

这是用户从picker中选择城市后的当前 可选(“城市”)

这个是用户选择城市后的 Optional("Orland")

【问题讨论】:

    标签: swift uibutton uipickerview didset


    【解决方案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 中实现 City Picker 视图,而不是仅为选择器创建新控制器。

    【讨论】:

    • 谢谢。我想在同一个视图中输入我的代码,但我不知道我在想什么。投票回答和推荐
    【解决方案2】:

    问题是您的 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      相关资源
      最近更新 更多