如何从 iOS AppDelegate 调用视图控制器函数?
How can I call a view controller function from an iOS AppDelegate?
我接到了来自远程推送通知的电话,其中包括我要显示的图像的路径。
AppDelegate 是:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
// get url from notification payload (shortened version)
let url = alert["imgurl"] as? NSString
let vc = ViewController()
vc.loadImage(url as String) // cannot find the imageView inside
}
...视图如下所示:
func loadImage(url:String) {
downloadImage(url, imgView: self.poolImage)
}
//
func getDataFromUrl(url:String, completion: ((data: NSData?) -> Void)) {
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) { (data, response, error) in
completion(data: NSData(data: data!))
}.resume()
}
func downloadImage(url:String, imgView:UIImageView){
getDataFromUrl(url) { data in
dispatch_async(dispatch_get_main_queue()) {
imgView.image = UIImage(data: data!)
}
}
}
我收到一个异常,说 imgView
为空(它被声明为 @IBOutlet weak var poolImage: UIImageView!
,我可以通过单击按钮调用 loadImage("http://lorempixel.com/400/200/")
来显示图像。
我在 Whosebug 上找到了几个相关的答案(上面引用了一个)但是 none 有效。
通过调用 @IBOutlet weak var poolImage: UIImageView!
,您将 poolImage
的初始化传递给故事板。由于您使用 let vc = ViewController()
初始化视图控制器,因此 vc
将知道它应该具有对 poolImage
的引用,因为您在 class 中声明了它,但是由于您实际上并没有初始化 vc
的视图(和子视图) poolImage
在加载 UI 之前保持为 nil。
如果在初始化vc
时需要引用一个UIImageView
,则需要手动实例化它:let poolImage = UIImageView()
编辑:您的 ViewController
实施 poolImage
目前看起来像这样:
class ViewController : UIViewController {
@IBOutlet weak var poolImage : UIImageView!
// rest of file
}
要通过 let vc = ViewController()
从 AppDelegate
访问 poolImage
,您必须使实现看起来像这样:
class ViewController : UIViewController {
/* ---EDIT--- add a placeholder where you would like
poolImage to be displayed in the storyboard */
@IBOutlet weak var poolImagePlaceholder : UIView!
var poolImage = UIImageView()
// rest of file
override func viewDidLoad() {
super.viewDidLoad()
/* ---EDIT--- make poolImage's frame identical to the
placeholder view's frame */
poolImage.frame = poolImagePlaceholder.frame
poolImagePlaceholder.addSubView(poolImage)
// then add auto layout constraints on poolImage here if necessary
}
}
这样poolImage
在创建ViewController
时可以参考
我相信在你打电话的那个时间点
let vc = ViewController()
它还没有被实例化。由于您将 @IBOutlet 用于 UIImageView,因此我假设您实际上拥有该 UIViewController。
也许可以通过以下方式更正:
let vc = self.storyboard?.self.storyboard?.instantiateViewControllerWithIdentifier("ViewControllerStoryboardID")
vc.loadImage("imageUrl")
self.presentViewController(vc!, animated: true, completion: nil)
让我知道它是否有效。 :)
编辑:您可以通过此方法调用情节提要的实例:
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var vc = storyboard.instantiateViewControllerWithIdentifier("ViewController") as! UIViewController
vc.loadImage("imageUrl")
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
我认为的原因是因为 imageView
可能不是 initialized
。请尝试以下解决方案。
向您的 viewController
添加另一个 init
方法,它接受 URLString
。一旦您收到 push notification
、initialize
您的 viewController
并将 imageURL
传递给新的 init
方法。
在新的initMethod
里面,可以使用imageURL
下载图片,设置为imageView
。现在你的 imageView
不应该是 null
并且错误应该不会发生。
如果您想以模态方式显示新的视图控制器,请进一步查看 rach 的答案。
如果您 ViewController 已经在屏幕上,您将需要更新它以显示您需要的信息。
如何执行此操作取决于您的根视图控制器设置。您的视图控制器是否嵌入到 UINavigationController 中?如果是这样,那么试试这个:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if let rootViewController = window?.rootViewController as? UINavigationController {
if let viewController = rootViewController.viewControllers.first as? ViewController {
let url = alert["imgurl"] as? NSString
viewController.loadImage(url as String)
}
}
}
如果不是,那么试试这个:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if let rootViewController = window?.rootViewController as? ViewController {
let url = alert["imgurl"] as? NSString
rootViewController.loadImage(url as String)
}
}
我接到了来自远程推送通知的电话,其中包括我要显示的图像的路径。
AppDelegate 是:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
// get url from notification payload (shortened version)
let url = alert["imgurl"] as? NSString
let vc = ViewController()
vc.loadImage(url as String) // cannot find the imageView inside
}
...视图如下所示:
func loadImage(url:String) {
downloadImage(url, imgView: self.poolImage)
}
//
func getDataFromUrl(url:String, completion: ((data: NSData?) -> Void)) {
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) { (data, response, error) in
completion(data: NSData(data: data!))
}.resume()
}
func downloadImage(url:String, imgView:UIImageView){
getDataFromUrl(url) { data in
dispatch_async(dispatch_get_main_queue()) {
imgView.image = UIImage(data: data!)
}
}
}
我收到一个异常,说 imgView
为空(它被声明为 @IBOutlet weak var poolImage: UIImageView!
,我可以通过单击按钮调用 loadImage("http://lorempixel.com/400/200/")
来显示图像。
我在 Whosebug 上找到了几个相关的答案(上面引用了一个)但是 none 有效。
通过调用 @IBOutlet weak var poolImage: UIImageView!
,您将 poolImage
的初始化传递给故事板。由于您使用 let vc = ViewController()
初始化视图控制器,因此 vc
将知道它应该具有对 poolImage
的引用,因为您在 class 中声明了它,但是由于您实际上并没有初始化 vc
的视图(和子视图) poolImage
在加载 UI 之前保持为 nil。
如果在初始化vc
时需要引用一个UIImageView
,则需要手动实例化它:let poolImage = UIImageView()
编辑:您的 ViewController
实施 poolImage
目前看起来像这样:
class ViewController : UIViewController {
@IBOutlet weak var poolImage : UIImageView!
// rest of file
}
要通过 let vc = ViewController()
从 AppDelegate
访问 poolImage
,您必须使实现看起来像这样:
class ViewController : UIViewController {
/* ---EDIT--- add a placeholder where you would like
poolImage to be displayed in the storyboard */
@IBOutlet weak var poolImagePlaceholder : UIView!
var poolImage = UIImageView()
// rest of file
override func viewDidLoad() {
super.viewDidLoad()
/* ---EDIT--- make poolImage's frame identical to the
placeholder view's frame */
poolImage.frame = poolImagePlaceholder.frame
poolImagePlaceholder.addSubView(poolImage)
// then add auto layout constraints on poolImage here if necessary
}
}
这样poolImage
在创建ViewController
时可以参考
我相信在你打电话的那个时间点
let vc = ViewController()
它还没有被实例化。由于您将 @IBOutlet 用于 UIImageView,因此我假设您实际上拥有该 UIViewController。
也许可以通过以下方式更正:
let vc = self.storyboard?.self.storyboard?.instantiateViewControllerWithIdentifier("ViewControllerStoryboardID")
vc.loadImage("imageUrl")
self.presentViewController(vc!, animated: true, completion: nil)
让我知道它是否有效。 :)
编辑:您可以通过此方法调用情节提要的实例:
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var vc = storyboard.instantiateViewControllerWithIdentifier("ViewController") as! UIViewController
vc.loadImage("imageUrl")
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
我认为的原因是因为 imageView
可能不是 initialized
。请尝试以下解决方案。
向您的 viewController
添加另一个 init
方法,它接受 URLString
。一旦您收到 push notification
、initialize
您的 viewController
并将 imageURL
传递给新的 init
方法。
在新的initMethod
里面,可以使用imageURL
下载图片,设置为imageView
。现在你的 imageView
不应该是 null
并且错误应该不会发生。
如果您想以模态方式显示新的视图控制器,请进一步查看 rach 的答案。
如果您 ViewController 已经在屏幕上,您将需要更新它以显示您需要的信息。
如何执行此操作取决于您的根视图控制器设置。您的视图控制器是否嵌入到 UINavigationController 中?如果是这样,那么试试这个:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if let rootViewController = window?.rootViewController as? UINavigationController {
if let viewController = rootViewController.viewControllers.first as? ViewController {
let url = alert["imgurl"] as? NSString
viewController.loadImage(url as String)
}
}
}
如果不是,那么试试这个:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if let rootViewController = window?.rootViewController as? ViewController {
let url = alert["imgurl"] as? NSString
rootViewController.loadImage(url as String)
}
}