Тогда я бы сделал это, чтобы выдвинуть новый контроллер представления:

м проекте XCode, когда пользователь нажимает на уведомление, я хочу сначала отправить их определенному элементу в моем tabBar, затем я хочу создать экземпляр контроллера представления и отправить объект этому контроллеру представления. У меня есть код, который отправляет их в tabBar, я хочу, но я не знаю, как создать их экземпляр для контроллера представления, сохраняя tabBar и панель навигации подключенными к контроллеру представления. Все ответы на это требуют, чтобы вы изменили корневой контроллер представления, и это заставляет меня терять соединение с моей вкладкой и панелью навигации, когда вызывается контроллер представления.

Пример из реальной жизни: Пользователь получает уведомление в Instagram, в котором говорится: «Джон начал подписываться на вас» -> пользователь нажимает на уведомление -> Instagram открывает и показывает вкладку уведомлений -> быстро отправляет пользователя в профиль «Джон», а когда пользователь нажимает кнопку «Назад», он отправляет их обратно в вкладка уведомления

Должен знать: причина, по которой я иду на определенную вкладку в первую очередь, заключается в том, чтобы получить контроллер навигации этой вкладки, потому что у контроллера представления, который я собираюсь, его нет.

Вот мой рабочий код по отправке пользователя на вкладку «Уведомления» (я добавил комментарии, чтобы вести себя как пример в Instagram для лучшего понимания):

if let tabbarController = self.window!.rootViewController as? UITabBarController {
    tabbarController.selectedViewController = tabbarController.viewControllers?[3] //goes to notifications tab
    if type == "follow" { //someone started following current user                            
        //send to user's profile and send the user's id so the app can find all the information of the user                    
    }
}

Ответы на вопрос(3)

что и ваш. Поэтому, хотя я сомневаюсь, что этот метод является правильным или идеальным для обработки push-уведомлений из AppDelegate (у меня все еще есть много вещей для изучения в iOS), я все еще делюсь им, потому что он работал для меня, и я считаю, что код все еще читабелен и довольно чистый.

Ключ должен знать уровни или стеки ваших экранов. Что такое childViewControllers, экран topMost, экран внизу и т. Д ...

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

Например, этот блок кода взят из AppDelegate моего проекта:

    func handleDeeplinkedJobId(_ jobIdInt: Int) {
        // Check if user is in Auth or in Jobs
        if let currentRootViewController = UIApplication.shared.keyWindow!.rootViewController,
            let presentedViewController = currentRootViewController.presentedViewController {
            if presentedViewController is BaseTabBarController {
                if let baseTabBarController = presentedViewController as? BaseTabBarController,
                    let tabIndex = TabIndex(rawValue: baseTabBarController.selectedIndex) {
                    switch tabIndex {
                    case .jobsTab:
....

....

                    if let jobsTabNavCon = baseTabBarController.viewControllers?.first,
                        let firstScreen = jobsTabNavCon.childViewControllers.first,
                        let topMostScreen = jobsTabNavCon.childViewControllers.last {

...
...

Итак, как вы можете видеть, я знаю иерархию экранов и, используя это знание, а также немного терпения при проверке, нахожусь ли я на нужном экране с помощьюконтрольные точки а такжеprintobject (po)Я получаю правильную ссылку. Наконец, в приведенном выше коде у меня естьtopMostScreen ссылка, и я могу использовать навигационный контроллер этого экрана, чтобы перейти к новому экрану, если я хочу.

Надеюсь это поможет!

 ap12306 нояб. 2017 г., 08:37
Где бы я мог указать, какой контроллер представления я хочу перейти. Причина, по которой я сначала перехожу на определенную вкладку, заключается в том, что я могу получить контроллер навигации этой вкладки, потому что у контроллера представления, который я собираюсь, нет
 Glenn06 нояб. 2017 г., 08:52
Я знаю, что вы знаете, как программно использовать viewController, не так ли? В этом случае, если вы хотите выдвинуть определенный контроллер представления (я заметил, что Facebook Messenger делает это, независимо от текущей вкладки), просто создайте новый экземпляр этого viewController, а затем нажмите его. Понял?
Решение Вопроса

let storyboard = UIStoryboard.init(name: "YourStoryboardName", bundle: nil)
let tabBarController = storyboard.instantiateViewController(withIdentifier: "YourTabBarController") as! UITabBarController

А потом навязать всеviewControllers TabBarController. Если ваши viewControllers встроены вUINavigationController? Если это так, то вместо этого вам понадобится навигационный контроллер:

let first = storyboard.instantiateViewiController(withIdentifier: "YourFirstNavigationController") as! UINavigationController
let second = storyboard.instantiateViewiController(withIdentifier: "YourSecondNavigationController") as! UINavigationController
let third = storyboard.instantiateViewiController(withIdentifier: "YourThirdNavigationController") as! UINavigationController

Также вам следует создать экземпляр желаемого ViewController:

let desiredVC = storyboard.instantiateViewController(withIdentifier: "desiredVC") as! ExampleDesiredViewController

Сделайте все NavigationControllers какviewControllers TabBarController:

tabBarController.viewControllers = [first, second, third]

И проверьте: это по вашему выбору.

if tabBarController.selectedViewController == first {

// Option 1: If you want to presen,t
first.present(desiredVC, animated: true, completion: nil)

// Option 2: If you want to push
first.pushViewController(desiredVC, animated. true)

}

Сделать tabBarController какrootViewController:

self.window = UIWindow.init(frame: UIScreen.main.bounds)   
self.window?.rootViewController = tabBarController
self.window?.makeKeyAndVisible()

Наконец: это ваш законченный код:

func openViewController() {

let storyboard = UIStoryboard.init(name: "YourStoryboardName", bundle: nil)
let tabBarController = storyboard.instantiateViewController(withIdentifier: "YourTabBarController") as! UITabBarController

let first = storyboard.instantiateViewiController(withIdentifier: "YourFirstNavigationController") as! UINavigationController
let second = storyboard.instantiateViewiController(withIdentifier: "YourSecondNavigationController") as! UINavigationController
let third = storyboard.instantiateViewiController(withIdentifier: "YourThirdNavigationController") as! UINavigationController

let desiredVC = storyboard.instantiateViewController(withIdentifier: "desiredVC") as! ExampleDesiredViewController

tabBarController.viewControllers = [first, second, third]

if tabBarController.selectedViewController == first {

// Option 1: If you want to present
first.present(desiredVC, animated: true, completion: nil)

// Option 2: If you want to push
first.pushViewController(desiredVC, animated. true)

}

self.window = UIWindow.init(frame: UIScreen.main.bounds)   
self.window?.rootViewController = tabBarController
self.window?.makeKeyAndVisible()

}

Если вы хотите, чтобы представить или нажмите ViewController, когда уведомление постукивает? Попробуйте что-то подобное:

extension AppDelegate: UNUserNotificationCenterDelegate {

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        switch response.actionIdentifier {
        case UNNotificationDefaultActionIdentifier:
            openViewController()
            completionHandler()

        default:
            break;
        }
    }
}
 David Vincent Gagne15 дек. 2017 г., 05:14
Святые макароны! Это кажется огромным количеством работы для меня. Я попробую, но кажется, что это должно быть проще.

1) Если этот контроллер представления является UINavigationController, вы можете просто отправить профиль из любого места:

if let tabNavigationController = tabbarController.viewControllers?[3] as? UINavigationController {
    tabbarController.selectedViewController = tabNavigationController
    let profileViewController = ProfileViewController(...)
    // ... set up the profile by setting the user id or whatever you need to do ...
    tabNavigationController.push(profileViewController, animated: true)    // animated or not, your choice ;)
}

2) В качестве альтернативы мне нравится управлять такими вещами непосредственно из моего подкласса контроллера представления (в данном случае, PostListViewController). У меня есть этот вспомогательный метод в быстром файле, который я включаю во все мои проекты:

extension UIViewController {
    var containedViewController: UIViewController {
        if let navController = self as? UINavigationController, let first = navController.viewControllers.first {
            return first
        }
        return self
    }
}

Тогда я бы сделал это, чтобы выдвинуть новый контроллер представления:

if let tabViewController = tabbarController.selectedViewController {
    tabbarController.selectedViewController = tabViewController
    if let postListViewController = tabViewController.containedViewController as? PostListViewController {
        postListViewController.goToProfile(for: user)    // you need to get the user reference from somewhere first
    }
}

Ваш ответ на вопрос