Swift: 如何关闭从 AppDelegate 启动的视图控制器和导航控制器
Swift: how to close view controller and navigation controller launched from AppDelegate
我的应用 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
否则它会是隐藏在酒吧里。
您可以创建导航控制器,但不要用它替换您的根控制器。只需在没有动画的情况下从您的标签栏控制器中呈现它。当您需要从通知中隐藏导航控制器时,只需将其关闭:
func showNavigation(){
tabBarController.presentViewController(navController, animated: false) {
}
}
func hideNavigation() {
tabBarController.dismissViewControllerAnimated(true) {
}
}
tabBarController 是你的 window?.rootViewController
已更新
而不是
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
window!.rootViewController = navigationController
self.window?.makeKeyAndVisible()
试试这个
rootTabBarController.presentViewController(navigationController, animated: true) {}
当您收到通知时,您的 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 中)上添加自定义导航栏,并将其 link 添加到您的 class 中,如下所示:
@IBOutlet weak var myNavigationBar: UINavigationBar
最后,您需要将后退按钮事件处理程序替换为以下内容:
func back(sender: UIBarButtonItem) {
self.dismissViewControllerAnimated(true, completion: nil)
}
我的应用 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
否则它会是隐藏在酒吧里。
您可以创建导航控制器,但不要用它替换您的根控制器。只需在没有动画的情况下从您的标签栏控制器中呈现它。当您需要从通知中隐藏导航控制器时,只需将其关闭:
func showNavigation(){
tabBarController.presentViewController(navController, animated: false) {
}
}
func hideNavigation() {
tabBarController.dismissViewControllerAnimated(true) {
}
}
tabBarController 是你的 window?.rootViewController
已更新
而不是
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
window!.rootViewController = navigationController
self.window?.makeKeyAndVisible()
试试这个
rootTabBarController.presentViewController(navigationController, animated: true) {}
当您收到通知时,您的 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 中)上添加自定义导航栏,并将其 link 添加到您的 class 中,如下所示:
@IBOutlet weak var myNavigationBar: UINavigationBar
最后,您需要将后退按钮事件处理程序替换为以下内容:
func back(sender: UIBarButtonItem) {
self.dismissViewControllerAnimated(true, completion: nil)
}