Opening ViewController In AppDelegate While Keeping Tabbar

前端 未结 3 1836
小鲜肉
小鲜肉 2020-12-10 21:14

In my Xcode project when a user taps on a notification I want to first send them to a certain item in my tabBar then I want to instantiate a view controller and send an obje

相关标签:
3条回答
  • 2020-12-10 21:53

    In my last live project, I'm using the same approach like yours. So even though I doubt this method is the correct or ideal for handling a push notification from the AppDelegate (I still got a lot of stuff to learn in iOS

    0 讨论(0)
  • 2020-12-10 21:57

    I can think of two ways to do that:

    1) If that view controller is a UINavigationController you can simply push the profile from wherever you are:

    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) Alternatively, what I like to do is control such things directly from my view controller subclass (in this case, PostListViewController). I have this helper method in a swift file that I include in all of my projects:

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

    Then I would do this to push the new view controller:

    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
        }
    }
    
    0 讨论(0)
  • 2020-12-10 22:09

    First of all, you'll to insatiate a TabBarController:

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

    And then insatiate all of the viewControllers of TabBarController. If your viewControllers is embedded in to the UINavigationController? If so, you'll to insatiate a Navigation Controller instead:

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

    Also you should instantiate your desired ViewController too:

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

    Make all of the NavigationControllers as viewControllers of TabBarController:

    tabBarController.viewControllers = [first, second, third]
    

    And check: It's about your choice.

    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)
    
    }
    

    Make tabBarController as a rootViewController:

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

    Finally: It's your completed code:

    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()
    
    }
    

    If you want to present or push ViewController when the notification is tapped? Try something like that:

    extension AppDelegate: UNUserNotificationCenterDelegate {
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    
            switch response.actionIdentifier {
            case UNNotificationDefaultActionIdentifier:
                openViewController()
                completionHandler()
    
            default:
                break;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题