Как открыть или модально представить контроллер представления из контроллера панели вкладок?

Как создать всплывающее окно, которое появляется при нажатии кнопки на панели вкладок? Я бы хотел что-то подобное: https://www.youtube.com/watch?v=zDWSaItF2ko.

Я пробовал много решений, но ни одно из них не помогло.

Например, я пробовал это с моим основным контроллером представления:

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

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    if viewController is PopupViewController {
        if let popupView = tabBarController.storyboard?.instantiateInitialViewController() {
            popupView.modalPresentationStyle = .fullScreen
            tabBarController.present(popupView, animated: true, completion: nil)

            return false
        }
    }
    return true
}

Вот несколько изображений, которые могут помочь:

Основная раскадровка:

Основная раскадровка

Всплывающая раскадровка:

Всплывающая раскадровка

Просмотреть код контроллера:

Просмотреть код контроллера


person Patrick Haertel    schedule 22.05.2018    source источник
comment
Я знаю, что мне нужно представить контроллер представления модально и поверх текущего контекста. На самом деле, нет. В упомянутом вами видео YouTube это не текущая контекстная презентация: это полноэкранная презентация. Вероятно, он использует настраиваемый контроллер презентации для установки размера / положения представленного представления (синий квадрат с Test и Done в нем).   -  person matt    schedule 22.05.2018


Ответы (1)


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

И, кстати, я бы порекомендовал другой способ создания экземпляра контроллера представления из раскадровки, а не:

tabBarController.storyboard?.instantiateInitialViewController()

Во-первых, перейдите к самому файлу раскадровки и в контроллере представления, который вы пытаетесь создать, измените Storyboard ID на что-то, например, на класс раскадровки (PopupViewController в вашем случае).

Затем вы захотите попробовать создать экземпляр самой раскадровки, используя инициализатор init(name: String, bundle storyboardBundleOrNil: Bundle?):

let storyboard = UIStoryboard(name: "Popup", bundle: nil)

А теперь создайте экземпляр контроллера представления, используя переменную storyboard следующим образом:

let popupViewController  = storyboard.instantiateViewController(withIdentifier: "PopupViewController") as! PopupViewController

Наконец, вы можете дать ему дополнительную конфигурацию и представить его на контроллере панели вкладок:

popupViewController.modalPresentationStyle = .fullScreen
tabBarController.present(popupViewController, animated: true)

Изменить

Кроме того, чтобы сделать его более Swifty, я рекомендую guard оператор для раннего выхода. Наконец, метод может выглядеть примерно так:

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    guard viewController is PopupViewController else { return true }
    let storyboard = UIStoryboard(name: "Popup", bundle: nil)
    let popupViewController = storyboard.instantiateViewController(withIdentifier: "PopupViewController") as! PopupViewController
    popupViewController.modalPresentationStyle = .fullScreen
    tabBarController.present(popupViewController, animated: true, completion: nil)
    return false
}
person Witek Bobrowski    schedule 22.05.2018
comment
Я получаю сообщение об ошибке Thread 1: signal SIGABRT, но никакие розетки не отключены. Он находится в файле делегата приложения. - person Patrick Haertel; 22.05.2018
comment
что такое полное сообщение об ошибке? не могли бы вы поделиться проектом на github или другом месте, чтобы я мог запустить его сам для лучшей проверки? - person Witek Bobrowski; 22.05.2018
comment
Я хотел бы сказать вам, что это всего лишь тестовый проект, чтобы я мог включить эту функцию в более крупное приложение. - person Patrick Haertel; 22.05.2018
comment
Хорошо, поэтому причиной сбоя является ссылка в Main.storyboard. Щелкните его и Popup в качестве справочной раскадровки. После того, как вы измените это, все должно работать, как ожидалось. - person Witek Bobrowski; 22.05.2018
comment
Это почти сработало, и я не могу поверить, что пропустил это; однако, когда всплывающее окно появляется, фон сначала становится прозрачным, показывая содержимое позади, но затем становится сплошным черным. Вот видео об этом youtu.be/SIfvVzMCF0M - person Patrick Haertel; 22.05.2018
comment
измените modalPresentationStyle на .overCurrentContext: popupViewController.modalPresentationStyle = .overCurrentContext В настоящее время контроллер представления отображается поверх контроллера панели вкладок (встроен в контроллер навигации), чтобы он покрыл весь экран, представьте его на контроллере навигации панели вкладок следующим образом: tabBarController.navigationController?.present(popupViewController, animated: true, completion: nil) - person Witek Bobrowski; 22.05.2018
comment
Рад, что смог помочь :) - person Witek Bobrowski; 22.05.2018
comment
Это не связанный с этим вопрос, но знаете ли вы, почему иногда не все имеет одинаковую цветовую кодировку, потому что в тестовом проекте, которым я поделился с вами, .modalPresentationStyle и другие объекты были окрашены в цвет; однако в моем более крупном проекте они были просто белыми по умолчанию. - person Patrick Haertel; 22.05.2018
comment
Вы про раскраску исходного кода? Это Xcode в лучшем виде. Чтобы исправить этот проект чистой сборки и перезапустить Xcode. Также удаление DerivedData помогает в некоторых экстремальных ситуациях. - person Witek Bobrowski; 22.05.2018
comment
Это устранило проблему. Спасибо. Я никогда не закрываю XCode, поэтому думаю, мне стоит начать. Я просто игнорировал это, но дошло до того, что меня это беспокоило, так что спасибо. - person Patrick Haertel; 22.05.2018
comment
Xcode иногда превращает кодирование в кошмар. Привыкайте перезагружать его несколько раз в день: P - person Witek Bobrowski; 22.05.2018