Как предотвратить многократное нажатие UIViewController в swift?

#ios #swift #navigation

#iOS #swift #навигация

Вопрос:

Когда я нажимаю несколько раз очень быстро на кнопку next, тогда контроллер более четко нажимается несколько раз, проблема в том, что нам нужно несколько раз нажать кнопку «Назад», чтобы перейти на предыдущий экран.

код следующей кнопки

 guard  let controller = UIStoryboard(name: "Filepreview", bundle: nil).instantiateViewController(withIdentifier: "FilepreviewVC") as? PreviewFileViewController else {return}
                            self.navigationController?.pushViewController(controller, animated: true)
  

Комментарии:

1. Как насчет отключения следующей кнопки после ее нажатия и включения ее только в viewDidAppear (или какой-либо другой метод, который будет вызван, когда вы вернетесь из нажатого VC)?

2. Я не отключал кнопку, фактически то же действие также выполняется при выборе строки в виде таблицы

3. Ну, а как насчет того, чтобы сделать это тогда? Или, по крайней мере, сделайте так, чтобы он «не работал» после 1 нажатия.

4. появится кнопка включения next в viewWillAppear

Ответ №1:

Не разрешайте пользователю нажимать кнопку несколько раз!

Это можно сделать, отключив кнопку непосредственно перед нажатием нового VC:

 nextButton.isEnabled = false
  

Если вы не хотите, чтобы пользователь видел, что кнопка отключена, или что триггер для нажатия не является чем-то, что можно отключить, просто используйте частное свойство для отслеживания вашего собственного «отключенного» состояния:

 private var nextButtonDisabled = false

// ...

// when you want to push the new VC, check nextButtonDisabled first!
if nextButtonDisabled {
    return
}
nextButtonDisabled = false
// push new VC here
  

И когда пользователь перейдет назад, viewDidAppear будет вызван, чтобы вы могли включить nextButton viewDidAppear :

 nextButton.isEnabled = true
// or
nextButtonDisabled = false
  

В качестве альтернативы, сделайте это в методе navigationController(_:didShow:animated:) делегирования.

 self.navigationController?.delegate = self

// ...

extension MyViewController : UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        if viewController == self {
            nextButtonDisabled = false
        }
    }
}
  

Комментарии:

1. как использовать этот NavigationController (_:didShow:animated:)?

2. на самом деле я должен реализовать это с помощью выбора строки в виде таблицы

3. @AJ Нет проблем, просто используйте подход частной собственности. И return сразу же, если это верно didSelectRowAt .

Ответ №2:

Подкласс UINavigationController и переопределите эту функцию

 public override func pushViewController(_ viewController: UIViewController, animated: Bool) {
    if
        let currentTopVC = viewControllers.last as? PreviewFileViewController,
        previewFileVC = viewController as? PreviewFileViewController,
        currentTopVC.file.id == previewFileVC.file.id {
        return
    }

    super.pushViewController(viewController, animated: animated)
}
  

Я предполагаю, что здесь существует какая-то идентификация за PreviewFileViewController пределами типа, поэтому могут быть два экземпляра, наложенных друг на друга, если они просматривают разные файлы. Если возможен только один предварительный просмотр, вы можете опустить последнюю строку раньше return .

Ответ №3:

 @IBAction func Submit(_ sender: Any) {
    for _ in 0..<10 {
        DispatchQueue.main.async {
            guard self.navigationController?.viewControllers.contains(where: {$0.isKind(of: TestVC.self)}) == false else { return }
            let vc = self.storyboard?.instantiateViewController(withIdentifier: "TestVC") as! TestVC
            vc.view.backgroundColor = self.generateRandomColor()
            self.navigationController?.pushViewController(vc, animated: true)
        }
    }
}
  

охранять self.NavigationController?.ViewControllers.contains(где: {$0.isKind(of: TestVC.self)}) == false else { return } используйте это, чтобы проверить, находится ли viewcontroller уже в стеке или нет.