Swift:如何关闭从AppDelegate启动的视图控制器和导航控制器

3

我的iOS应用主骨架使用TabBarController。然而,当通知到达时会有额外的行为。当接收到推送通知时,我的应用会执行以下操作:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    //application.applicationIconBadgeNumber = 0
    //application.cancelAllLocalNotifications()
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let notificationController = storyboard.instantiateViewControllerWithIdentifier("DynamicEventsViewController") as! DynamicEventsViewController
    notificationController.isLoadedFromNotification = true
    notificationController.eventTitle = userInfo["aps"]!["alert"] as! String
    notificationController.eventDescription = userInfo["aps"]!["message"] as! String
    let navigationController = UINavigationController()
    navigationController.pushViewController(notificationController, animated: true)
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    window!.rootViewController = navigationController
    self.window?.makeKeyAndVisible()

}

这是相关实例化视图控制器的代码:

class DynamicEventsViewController:UIViewController {

@IBOutlet weak var upDistanceConstraint: NSLayoutConstraint!
@IBOutlet weak var dynamicEventTitle:UITextField!
@IBOutlet weak var dynamicEventDescription:UITextView!

var eventTitle:String? = nil
var eventDescription:String? = nil

var isLoadedFromNotification = false


override func viewDidLoad() {
    super.viewDidLoad()

        self.navigationItem.titleView = UIImageView(image: UIImage(named: "icons/bar.png"))
        self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()

        if (self.navigationItem.leftBarButtonItem == nil) {
            let leftButton = UIBarButtonItem(title: "Chiudi", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(DynamicEventsViewController.back(_:)))
            self.navigationItem.leftBarButtonItem = leftButton
        }

    if (self.eventTitle != nil && self.eventDescription != nil) {
        self.dynamicEventTitle.text = self.eventTitle?.uppercaseString
        self.dynamicEventDescription.text = self.eventDescription
    }
}

func back(sender: UIBarButtonItem) {
  self.navigationController?.popViewControllerAnimated(true)
}

}

无论如何,如果我点击“Chiudi”按钮,视图控制器都不会关闭,而我希望应用程序返回到“TabBarController”。哪种方法是正确的?
最终解决方案: 在AppDelegate.swift文件中的didReceiveLocal(Remote)Notification()函数中执行以下操作:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let notificationController = storyboard.instantiateViewControllerWithIdentifier("DynamicEventsViewController") as! DynamicEventsViewController
    notificationController.isLoadedFromNotification = true
    notificationController.eventTitle = userInfo["aps"]!["alert"] as? String
    notificationController.eventDescription = userInfo["aps"]!["message"] as? String
    notificationController.isLoadedFromNotification = true

    if let tabBarController = self.window?.rootViewController {
        tabBarController.presentViewController(notificationController, animated: true, completion: nil)
    }

当我在我的视图控制器中执行以下操作:

if (isLoadedFromNotification) {
        self.upDistanceConstraint.constant = 90

        let navigationBar:UINavigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.frame.size.width, 80))
        navigationBar.backgroundColor = UIColor.whiteColor()

        let navigationItem:UINavigationItem = UINavigationItem()

        let leftButton:UIBarButtonItem = UIBarButtonItem(title: "Chiudi", style: .Plain, target: self, action: #selector(DynamicEventsViewController.exit(_:)))

        navigationItem.titleView = UIImageView(image: UIImage(named: "icons/bar.png"))
        navigationItem.leftBarButtonItem = leftButton
        self.navigationItem.titleView = UIImageView(image: UIImage(named: "icons/bar.png"))

        navigationBar.items = [navigationItem]

        self.view.addSubview(navigationBar)

}

这里的self.upDistanceConstraint是一个NSLayoutConstraint,表示工具栏和视图控制器中第一个组件(在我的情况下是一个UITextField)之间的距离。如果没有这个约束,该组件将被工具栏遮盖。

2个回答

2

当您收到通知时,您的TabBarController已经成为应用程序的rootViewController:您不需要将notificationController嵌入导航控制器中,并且可以通过以下代码替换AppDelegate中的代码:

    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let notificationController = storyboard.instantiateViewControllerWithIdentifier("DynamicEventsViewController") as! DynamicEventsViewController
    notificationController.isLoadedFromNotification = true
    notificationController.eventTitle = userInfo["aps"]!["alert"] as! String
    notificationController.eventDescription = userInfo["aps"]!["message"] as! String

    if let tabBarController = self.window?.rootViewController {
        tabBarController.presentViewController(notificationController, animated: true, completion: nil)
    }

}

然后你需要在DynamicEventsViewController(在你的Storyboard中)上添加一个自定义导航栏,并将其与你的类链接起来,如下所示:

@IBOutlet weak var myNavigationBar: UINavigationBar

最后,您需要用以下内容替换返回按钮事件处理程序:

func back(sender: UIBarButtonItem) {
        self.dismissViewControllerAnimated(true, completion: nil)
}

1
你可以创建导航控制器,但不要用它替换根控制器。只需从选项卡栏控制器中呈现它,不需要动画。当你需要从通知中隐藏导航控制器时,只需将其解散:
func showNavigation(){
    tabBarController.presentViewController(navController, animated: false) {  
    }
}

func hideNavigation() {
    tabBarController.dismissViewControllerAnimated(true) {
    }
}

tabBarController是你的窗口?.rootViewController

已更新

而不是

self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
window!.rootViewController = navigationController
self.window?.makeKeyAndVisible()

尝试这个。
rootTabBarController.presentViewController(navigationController, animated: true) {}

是的,我会立即尝试!这就是我在应用程序委托中所做的:let rootTabBarController = self.window?.rootViewController as! UITabBarController - SagittariusA
2
@LoryLory,请查看此链接:http://stackoverflow.com/questions/23346948/how-to-present-a-navigation-controller-embedded-in-a-tab-bar-controller-when-rec - Sasha Kozachuk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接