Nano Hash - криптовалюты, майнинг, программирование

Как синхронизировать результат UIAlertController?

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

Это мой код:

extension CDFFormController: UINavigationBarDelegate {

    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        if let entityViewController = self.topViewController as? MyEntityViewController {
            if entityViewController.isEditing {
                let semaphore = DispatchSemaphore(value: 0)
                var result = false
                let alert = UIAlertController(title: "Leave the view?", message: nil, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "leave", style: .default, handler: { _ in
                    result = true
                    semaphore.signal()
                }))
                alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: { _ in
                    semaphore.signal()
                }))
                entityViewController.present(alert, animated: true, completion: nil)

                semaphore.wait()
                return result
            } else {
                return true
            }
        } else {
            return true
        }

    }

}

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

Или любое другое решение?


  • .isBeingPresented UIAlertController может оказаться полезным в вашем случае. Я использовал его в своем обходном пути: stackoverflow.com/a/43507005/5329717 для другой проблемы, возможно, вы ее найдете полезно в некотором роде. 24.04.2017
  • Вместо этого используйте обработчик завершения. 24.04.2017
  • Этот метод делегата вызывается в основном потоке (потоке пользовательского интерфейса), событие контроллера предупреждений не может отображаться, пока оно не вернется! 24.04.2017
  • @Sulthan Не могли бы вы дать больше объяснений? 24.04.2017

Ответы:


1

Я не уверен, что это будет работа. Я не проверял это.

extension CDFFormController: UINavigationBarDelegate {

public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
    if let entityViewController = self.topViewController as? MyEntityViewController {
        if entityViewController.isEditing {
            let alert = UIAlertController(title: "Leave the view?", message: nil, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "leave", style: .default, handler: { _ in
                let saveDelegate = navigationBar.delegate;
                navigationBar.delegate = nil;
                navigationBar.popItem(animated:YES);
                navigationBar.delegate = saveDelegate;
            }))
            alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler:nil))
            entityViewController.present(alert, animated: true, completion: nil)


            return false
        } else {
            return true
        }
    } else {
        return true
    }

}

}

Другой способ — использовать RunLoop. Но мне это не нравится.

extension CDFFormController: UINavigationBarDelegate {

    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        if let entityViewController = self.topViewController as? MyEntityViewController {
            if entityViewController.isEditing {
                let state = 0
                var result = false
                let alert = UIAlertController(title: "Leave the view?", message: nil, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "leave", style: .default, handler: { _ in
                    state = 1

                }))
                alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: { _ in
                    state = 2
                }))
                entityViewController.present(alert, animated: true, completion: nil)

                while (state == 0)
                {
                   RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.5))
                }
                return state == 1
            } else {
                return true
            }
        } else {
            return true
        }

    }

}
24.04.2017
  • Для первого решения выдается *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot manually set the delegate on a UINavigationBar managed by a controller.', iOS не хочет, чтобы я менял делегата, но это хороший момент. Я думаю, что могу использовать новое свойство флага, чтобы делать то же самое :) 24.04.2017
  • Второй мне тоже не нравится, мертвая петля никому не нравится :P 24.04.2017
  • К сожалению, он выдает еще один *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot call popNavigationItemAnimated: directly on a UINavigationBar managed by a controller.'. Но я не хочу сам управлять UINavigationBar :( 24.04.2017
  • Насколько я понимаю, вы используете navigationcontroller. Поэтому измените pop на панель навигации, а pop — на навигационный контроллер. Также вы можете изменить делегата для навигационного контроллера. 25.04.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..