Как я могу сохранить значение UIStepper, чтобы оно оставалось, когда я возвращаюсь к его контроллеру представления

У меня возникают трудности с сохранением/перемещением данных между двумя контроллерами представления. В частности, у меня есть UIStepper на втором контроллере представления, который действует как параметр, изменяющий переменную, используемую на первом контроллере представления. Когда я возвращаюсь ко второму контроллеру представления, степпер возвращается к своему значению по умолчанию, которое я установил в инспекторе атрибутов раскадровки.

Я считаю, что мне нужно сделать значение по умолчанию UIStepper равным его новому значению после его сохранения, но я не знаю, как это сделать. У меня такая же проблема с сегментированным элементом управления, когда я хочу, чтобы любой оставшийся выбор сохранялся в качестве настройки в моем приложении.

'''

Контроллер первого представления:

var volume: Double = 12 
var speed: Double = 10

class ViewController: UIViewController {

    @IBAction func switchOver(_ sender: Any) {
    
    guard let destinationVC = storyboard?.instantiateViewController(withIdentifier: "popUpID") as? popUpViewController else {
        return
    }
    
    present(destinationVC, animated: true, completion: nil)

    }
}

Второй контроллер представления:

@IBOutlet weak var volumeLabel: UILabel!

@IBAction func volumeStepper(_ sender: UIStepper) {
    volume = sender.value
    volumeLabel.text = String(sender.value) + " fl oz"


@IBAction func currentSpeed(_ sender: UISegmentedControl) {

    switch sender.selectedSegmentIndex {
        case 0:
            speed = 10              // takes 10 seconds 
        case 1:
            speed = 300             // takes 5 minutes 
        case 2:
            speed = 1200            // takes 20 minutes
        case 3:
            speed = 2400            // takes 40 minutes 
        default:
            speed = 10
    }
}

@IBAction func closePopUp(_ sender: Any) {      
    dismiss(animated: true, completion: nil)
}

'''


person Matthew R    schedule 31.08.2020    source источник
comment
Добавьте код для первого и второго контроллера представления. Кроме того, вы хотите сохранить данные в нескольких сеансах приложения?   -  person PGDev    schedule 31.08.2020
comment
Попробуйте использовать UserDefaults   -  person HHumorous    schedule 31.08.2020
comment
Когда мне нужно сохранить пользовательские настройки между сессиями, я обычно использую UserDefaults. От контроллера к контроллеру вы также можете установить глобальную переменную в синглтоне.   -  person claude31    schedule 31.08.2020
comment
@claude31 прямо сейчас я использую для этого глобальные переменные. Моя проблема заключается в том, чтобы выяснить, как использовать переменную и сделать ее новым значением шагового двигателя по умолчанию в коде. (например, myStepper.value = myGlobalVariable)?   -  person Matthew R    schedule 31.08.2020
comment
@PGDev Я добавил код из обоих контроллеров представления - сохранить код или нет, мне нужно знать, как инициализировать степпер с новым значением по умолчанию   -  person Matthew R    schedule 31.08.2020
comment
В viewDidload или viewDidAppear или в IBAction для возврата segue, если вы используете unwindSegue, установите значение stepper на глобальное значение var. Нужно увидеть больше кода, чтобы быть более конкретным.   -  person claude31    schedule 31.08.2020
comment
Этот вопрос задают чуть ли не раз в день. Просто найдите данные для передачи между контроллерами представления, например stackoverflow. ком/вопросы/5210535/   -  person Andreas Oetjen    schedule 31.08.2020
comment
Попробуйте также добавить @IBOutlet для степпера. Затем в ViewDidLoad установите значение шагового двигателя на желаемое значение.   -  person Nate4436271    schedule 31.08.2020


Ответы (1)


Если я правильно понимаю проблему, я думаю, что вам нужно решить две проблемы.

  1. Каким-то образом второму контроллеру представления необходимо сообщить первому контроллеру представления о внесении изменений. NotificationCenter — один из способов сделать это
  2. Обновите значение шагового двигателя до сохраненного значения.

В контроллере первого представления

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    
        if let value = UserDefaults.standard.value(forKey: "Stepper") as? Double {
            label.text = String(describing: value)
        }
        //subscribe to changes
        NotificationCenter.default.addObserver(self, selector: #selector(stepperDidChange), name: Notification.Name("stepperDidChangeValue"), object: nil)
    
    }

    // Handle Notification
    @objc func stepperDidChange() {
        if let value = UserDefaults.standard.value(forKey: "Stepper") as? Double {
            label.text = String(describing: value)
        }
    }
}

А затем во втором View Controller

class SecondViewController: UIViewController {

    @IBOutlet weak var stepper: UIStepper!
    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
    
        if let value = UserDefaults.standard.value(forKey: "Stepper") as? Double {
            stepper.value = value
            label.text = String(describing: value)
        }
    }

    @IBAction func didChangeStepper(_ sender: UIStepper) {
        label.text = String(describing: sender.value)

        // save the changed value to UserDefaults
        UserDefaults.standard.setValue(sender.value, forKey: "Stepper")
        //Post to Notification Center that the value has changed
        NotificationCenter.default.post(Notification.init(name: Notification.Name("stepperDidChangeValue")))
    }

}

Эти два представления связаны настоящим переходом в раскадровке.

Вот небольшая демонстрация, которую я создал для демонстрации

person Nate4436271    schedule 31.08.2020