Иногда состояния UIButton UserDefaults загружаются неправильно

У меня возникли проблемы с загрузкой UserDefaults правильного логического значения для состояния кнопки. Ну, у меня есть две кнопки в одном и том же TableViewCell. Одна кнопка называется «OzButton», а другая — «mLButton». Хотя я написал код, и до сих пор он работал, иногда будут редкие случаи, когда я нажимаю, например, кнопку mL, а затем после перезапуска приложения оно выделяет кнопку OzButton вместо кнопки mL, хотя я уже постучал по нему. Я программно создаю UIButtons и свои цели. Я не уверен, что я делаю неправильно здесь. Я приложу изображение View Controller для наглядности.

Просмотреть изображение контроллера

Я застрял на этом некоторое время...

Я не уверен, что я делаю неправильно... пожалуйста, помогите!

var didOzTapped = Bool()
let conversionDefaults = UserDefaults.standard

lazy var ozButton: UIButton = {
    let button = UIButton(type: .system)
    button.setTitle("oz", for: .normal)
    button.setTitleColor(.black, for: .normal)
    button.tintColor = .clear
    button.layer.cornerRadius = 15
    button.addTarget(self, action: #selector(handleOzTap), for: .touchUpInside)
    return button
}()

lazy var mlButton: UIButton = {
    let button = UIButton(type: .system)
    button.setTitle("mL", for: .normal)
    button.setTitleColor(.black, for: .normal)
    button.titleLabel?.contentMode = .center
    button.titleLabel?.font = UIFont(name: "SFProDisplay-Bold", size: 16)
    button.backgroundColor = .white
    button.addTarget(self, action: #selector(handleMLTap), for: .touchUpInside)
    return button
}()

override func viewWillAppear(_ animated: Bool) {
    checkForConversionDefaults()
}

@objc func handleOzTap() {
    didOzTapped = true

    mlButton.isSelected = !didOzTapped

    ozButton.isEnabled = false

    mlButton.isEnabled = true

    ozButton.backgroundColor = .blue
    mlButton.backgroundColor = .white

    conversionDefaults.set(didOzTapped, forKey: "tapTheOz")        
}

@objc func handleMLTap() {

    didOzTapped = false

    ozButton.isSelected = didOzTapped

    ozButton.isEnabled = true

    mlButton.isEnabled = false

    mlButton.backgroundColor = .blue
    ozButton.backgroundColor = .white

    conversionDefaults.set(didOzTapped, forKey: "tapTheOz")
}

fileprivate func checkForConversionDefaults() {

    if conversionDefaults.bool(forKey: "tapTheOz") {
        print("ConversionDefaults: true")

        ozButton.backgroundColor = .blue
        mlButton.backgroundColor = .white

    } else {
        print("ConversionDefaults: false")

        mlButton.backgroundColor = .blue
        ozButton.backgroundColor = .white
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let profileCell = ProfileCell(style: .default, reuseIdentifier: nil)

    switch indexPath.row {
    case 0:

    case 1:
// some code 

    case 2:            
        profileCell.cellView.addSubview(measurementLabel)
        measurementUnitLabel.anchor(top: profileCell.cellView.topAnchor, leading: profileCell.cellView.leadingAnchor, bottom: .none, trailing: profileCell.cellView.trailingAnchor, padding: .init(top: 5, left: 20, bottom: 0, right: 20))

// created a stackView called ozMilButtonStackView (ozButton and mLButton)
 profileCell.cellView.addSubview(ozMilButtonStackView)
        ozMilButtonStackView.anchor(top: measurementUnitLabel.bottomAnchor, leading: profileCell.cellView.leadingAnchor, bottom: profileCell.cellView.bottomAnchor, trailing: profileCell.cellView.trailingAnchor, padding: .init(top: 0, left: 100, bottom: 10, right: 100))

    default:
        break
    }

    return profileCell
}

person georrgee    schedule 23.11.2019    source источник
comment
добавьте это conversionDefaults.synchronize() после установки значения в UserDefaults   -  person SGDev    schedule 23.11.2019
comment
Вероятно, это проблема по умолчанию в симуляторе. UISegmentedControl ночь работает лучше, чем две кнопки. Вы также должны проверить доступность, если это настоящее приложение; убедитесь, что люди с различными нарушениями зрения могут определить, какая кнопка нажата. То же самое для озвучивания   -  person Paulw11    schedule 23.11.2019
comment
Я ценю ваш ответ Paulw11! Использование на реальном устройстве было последовательным и правильным... до сих пор. При работе на симуляторах он выполняет свою работу, но опять же в тех редких случаях, UserDefaults будет странным при загрузке правильного значения... Я обязательно попробую способ UISegmentedControl   -  person georrgee    schedule 23.11.2019


Ответы (2)


Итак, после экспериментов. Похоже, это была проблема с симулятором (я использовал симулятор iPhone X). При запуске на реальном устройстве не было проблем с сохранением и обновлением UserDefaults.

Я использовал другой симулятор (iPhone 6s Plus) и по-прежнему не имел никаких проблем с UserDefaults.

Не знаю, почему iPhone X Sim вызывал у меня проблемы...

person georrgee    schedule 02.12.2019

добавьте это conversionDefaults.synchronize() после установки значения в UserDefaults.

Код :

@objc func handleOzTap() {
    didOzTapped = true

    mlButton.isSelected = !didOzTapped

    ozButton.isEnabled = false

    mlButton.isEnabled = true

    ozButton.backgroundColor = .blue
    mlButton.backgroundColor = .white

    conversionDefaults.set(didOzTapped, forKey: "tapTheOz") 
    conversionDefaults.synchronize()

}
person SGDev    schedule 23.11.2019
comment
Поэтому я добавил эту строку кода. Перезапустите приложение, оно было настроено на кнопку mL, и я нажал кнопку Oz. Снова перезапускаю приложение, и оно снова настраивается на кнопку mL... к вашему сведению, я использую iPhone X Simulator. Я также пытаюсь использовать свое реальное устройство, оно было последовательным и правильным ... но я боюсь, что оно не будет оставаться последовательным, ха-ха. Не уверен, что это проблема симулятора. - person georrgee; 23.11.2019
comment
@georRGee Понятия не имею, в моем симуляторе все работает нормально, можете ли вы проверить неправильное значение в UserDefaults или ваш пользовательский интерфейс настроен неправильно, значит проверьте значение UserDefaults в случае перезапуска. - person SGDev; 23.11.2019
comment
Как странно... Я использую операторы отладчика и печати. Все имеет правильные значения ... даже при загрузке контроллера UserDefaults содержит правильное логическое значение ... опять же, иногда он возвращается к предыдущему состоянию. Я не уверен, что моя логика неверна... Я обновил свой вопрос и код того, как я устанавливаю пользовательский интерфейс. Плохая практика - настраивать представления внутри функции cellForRow или это не имеет значения? - person georrgee; 23.11.2019
comment
добавьте mlButton и ozButton внутрь ячейки вместо добавления. - person SGDev; 23.11.2019
comment
Я не минусовал тебя, SGDev. Возможно, кто-то другой сделал - person georrgee; 23.11.2019
comment
Ну, на симуляторе такая же проблема. Итак, чтобы ответить на ваш вопрос... нет. Еще нет. Я продолжаю тестировать. Благодарю за ваш ответ - person georrgee; 23.11.2019
comment
последнее, что вы можете попробовать, это просто перезагрузить симулятор, а затем повторно протестировать его. Пусть это поможет вам. - person SGDev; 23.11.2019
comment
О, ладно, позвольте мне попробовать. Будем держать вас в курсе - person georrgee; 23.11.2019