В быстром для iO у меня есть блок кода if / else, реагирующий на изменения в UISwitch. Как вернуть выключатель в некоторых ситуациях? - PullRequest
0 голосов
/ 16 января 2019

В моем быстром iOS-приложении у меня есть простой элемент управления UISwitch. Я подключил выход с измененным значением к своему @IBAction. Код выглядит так:

@IBAction func userDidSelectVisibiltySwitch(_ sender: Any) {

    if self.visibilitySwitch.isOn {
       if badCondition {
           self.visibilitySwith.setOn(false, animated: false)

          return
       }
     } else { // Strangely, it executes the else (I think because the compiler is evaluating the isOn condition again when it arrives to the else {}
        // work to be done if the user has turned off the switch
     }
}

Я подозреваю, что в этом случае, поскольку я выключаю переключатель перед вычислением else, компилятор выполняет оператор else {}, потому что он снова вычисляет вышеприведенное выражение isOn. Но как это возможно, учитывая, что я поместил инструкцию возврата? это действительно за мной. Подтверждением моего подозрения является тот факт, что, если я отправляю с помощью GCD оператор self.visibilitySwith.setOn (false, animated: false) ', отправив его с помощью GCD, он будет работать должным образом без выполнения оператора else {}, потому что оценка else требует место до того, как контроль отключен моим заявлением. Мой код теперь выглядит так, и он работает:

@IBAction func userDidSelectVisibiltySwitch(_ sender: Any) {

    if self.visibilitySwitch.isOn {
       if badCondition {
            DispatchQueue.main.async {
               self.visibilitySwith.setOn(false, animated: false)
            }
            return
       }
     } else { // In this case it is normal, it does not execute the else {}
        // work to be done if the user has turned off the switch
     }
}

Я думаю, что мне не хватает чего-то важного в этом случае. Любая помощь очень ценится. Я уже предоставил решение, но я хочу понять проблему. Большое спасибо

1 Ответ

0 голосов
/ 16 января 2019

Вместо того, чтобы обращаться к UISwitch через аргумент sender, вы переходите непосредственно к тому, что, как я полагаю, является значением IBOutlet. Вместо этого вы можете получить доступ к отправителю, как описано ниже:

@IBAction func userDidSelectVisibiltySwitch(_ sender: UISwitch) {
    if sender.isOn && badCondition {
        sender.setOn(false, animated: false)
    } else { // In this case it is normal, it does not execute the else {}
        // work to be done if the user has turned off the switch
    }
}

Причина, по которой ваше исправление работает, вероятно, из-за небольшой задержки, вызванной вызовом отправки, что позволяет значению IBOutlet обновить свое значение.

Я также пошел дальше и объединил ваше заявление if, поскольку предоставленный вами образец не требует вложенной проверки.

ОБНОВЛЕНО НА ОСНОВЕ КОММЕНТАРИИ РМАДДИ

Это решение вызвало у меня немного запаха кода, и после дальнейшего изучения я смог воспроизвести сценарии, описанные OP. Это было достигнуто установкой действия в раскадровке, как показано здесь:

enter image description here

С этой настройкой я увидел следующее:

  • Исходный код, отправленный OP, потерпит неудачу
  • Добавление DispatchQueue, как продемонстрировано OP, исправит коммутатор после небольшой задержки
  • Мое опубликованное решение будет работать правильно

Предполагая, что это то, что сделал OP, первое исправление будет состоять в том, чтобы изменить событие на Value Changed. Тогда, как указано в комментарии rmaddy, это будет выполнено независимо от того, используете ли вы аргумент или IBOutlet. Исходя из первоначального вопроса, моя интерпретация заключалась в том, что возникла проблема с выходным значением и состоянием синхронизации в интерфейсе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...