Swift с использованием обработчиков завершения для блокировки представления в одном контроллере для отражения в другом

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

Я хочу реализовать следующее.

  1. Пользователь появляется на экране (контроллер представления) и готов «заблокировать» выбор
  2. Значок блокировки/разблокировки находится в правом верхнем углу панели навигации.
  3. Пользователь щелкает значок, чтобы заблокировать
  4. Отображается окно UIAlert, подтверждающее, что пользователь хочет заблокировать свой выбор
  5. Пользователь подтверждает
  6. Пользователю предоставляется другое представление, позволяющее ввести PIN-код.
  7. Если они нажмут кнопку «Отмена», закройте контроллер представления PIN-кода, и состояние блокировки останется разблокированным.
  8. Если они нажмут «Отправить», закройте контроллер модального представления PIN-кода.
  9. Значок в правом верхнем углу должен измениться на значок «Заблокировано».

Кажется, все работает, за исключением того, что значок и состояние не обновляются должным образом, поскольку может показаться, что как только пользователь получает контроллер модального представления PIN-кода, код просто продолжает выполняться, в котором статус «Блокировка» остается как «Разблокировано» поскольку пользователь не ввел свой PIN-код и не нажал «Отправить», что изменит статус «Блокировка»?

Могут ли обработчики завершения «приостановить» состояние до тех пор, пока пользователь не отобразит модальное окно, после чего введет PIN-код, а затем отправит свой PIN-код... и помните, что пользователь также может нажать «Отмена», если он хочет больше не блокировать по какой-либо причине?


person Famic Tech    schedule 19.12.2018    source источник
comment
Вы говорите об обработчике завершения контроллера представления? который вызывается сразу после представления контроллера представления?   -  person Andrey Chernukha    schedule 19.12.2018
comment
было бы лучше, если бы вы показали свой код, чтобы людям не приходилось догадываться, что именно происходит   -  person Andrey Chernukha    schedule 19.12.2018


Ответы (1)


В FirstViewController вы можете добавить по завершению щелчка по блокировке/разблокировке элемента навигации,

func lockOrUnlock() {
    let pinVC = PinViewController()
    pinVC.onCompletion = { [weak self] (isPinChanged) in
        //change the lock/unlock icon based on isPinChanged flag
        //if true then update the status else revert the status to prev one
        }
    let pinVCNavController = UINavigationController(rootViewController: pinVC)
    pinVCNavController.modalPresentationStyle = .currentContext
    self.present(pinVCNavController, animated: true, completion: nil)
}

В PinViewController верните значение флага как true or false в зависимости от выбора пользователя, отправить или отменить действие,

var onCompletion: ((Bool) -> Void)?

override func viewDidLoad() {
    super.viewDidLoad()
    let cencelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelAction))
    self.navigationItem.leftItemsSupplementBackButton = true
    self.navigationItem.leftBarButtonItem = cencelButton
}

@IBAction func submitAction(_ sender: Any) {
    self.onCompletion?(true)
}

func cancelAction() {
    self.onCompletion?(false)
}
person Bappaditya    schedule 19.12.2018
comment
Так что, по сути, это заменило использование protocols вместо completion handlers? Я спрашиваю, потому что в настоящее время я использую протокол для передачи информации родительскому VC из дочернего VC. Но может показаться, что код просто продолжает двигаться вперед, не дожидаясь ввода от пользователя, поэтому статус никогда не меняется на заблокированный «вовремя», чтобы код распознал, что значение изменилось. - person Famic Tech; 19.12.2018
comment
Я бы рискнул сказать, что в вашем подходе дескриптор завершения будет ждать, сколько бы времени ни потребовалось пользователю для ввода/действия, прежде чем он изменит заблокированный статус на основе нажатия кнопки «Отправить» или «Отмена» и отклонения модального представления. - person Famic Tech; 19.12.2018
comment
вы также можете использовать протокол, завершение - это только один из вариантов достижения решения - person Bappaditya; 19.12.2018
comment
Я использовал протокол, и, как я уже сказал, кажется, что код просто продолжает двигаться вперед, и к тому времени, когда используется «Отправить» или «Отменить», код на основном потоке выполнил обновление Firebase, используя начальное LockStatus как ложное. - person Famic Tech; 19.12.2018