Как обновить .setTitle для UIButton, используя didSet? - PullRequest
0 голосов
/ 26 декабря 2018

Я работаю с контроллером представления регистрации профиля, я хочу обновить заголовок своей UIButton, когда пользователь выбирает город из UIPickerController.Название кнопки не обновляется после того, как пользователь выбирает город.

Я пытаюсь использовать 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]
}
}

Моя консоль печатает текущий заголовок до и после.Это консоль:

Этот ток является текущим после того, как пользователь выбирает город из средства выбора Необязательный ("Город")

Этот - после того, как пользователь выбирает город Необязательно("Орланд")

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Ваша проблема в следующем методе, в котором вы создаете новый контроллер и присваиваете 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 для отправки данных между ViewControllers.

Пример:

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

    /////
}

Но я порекомендую вам реализовать представление City Picker внутри PersonalInfoController вместо создания нового контроллера только для сборщика.

0 голосов
/ 26 декабря 2018

Проблема в том, что ваш 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)
...