我正在通过远程推送通知接听电话,其中包含我想要显示的图像路径。
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)
}
// http://stackoverflow.com/a/28942299/1011227
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/")
来显示图片。
我在stackoverflow上找到了几个相关的答案(一个在上面引用)但没有工作。
答案 0 :(得分:4)
如果您想以模态方式显示新的视图控制器,请进一步查看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)
}
}
答案 1 :(得分:2)
我相信你打电话的时间
let vc = ViewController()
尚未实例化。由于您正在为UIImageView使用@IBOutlet,我假设您确实拥有该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()
答案 2 :(得分:1)
通过调用@IBOutlet weak var poolImage: UIImageView!
,您将poolImage
的初始化传递给了故事板。由于您使用let vc = ViewController()
初始化视图控制器,vc
会知道它应该引用poolImage
,因为您在课程中声明了它,但是因为您不是实际初始化vc
的视图(和子视图)poolImage
在UI加载之前仍为零。
如果您需要在初始化UIImageView
时引用vc
,则必须手动实例化它:let poolImage = UIImageView()
编辑:您ViewController
的{{1}}实施目前看起来像这样:
poolImage
要从class ViewController : UIViewController {
@IBOutlet weak var poolImage : UIImageView!
// rest of file
}
通过poolImage
访问AppDelegate
,您必须使实施看起来像这样:
let vc = ViewController()
这样,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
时供参考。
答案 3 :(得分:0)
我认为原因是因为imageView
可能不是initialized
。尝试以下解决方案。
将另一个init
方法添加到接受viewController
的{{1}}。收到URLString
push notification
initialize
后viewController
并将imageURL
传递给新init
方法。
在新initMethod
内,您可以使用imageURL
下载图片并将其设置为imageView
。现在,您的imageView
不应为null
,并且不应出现错误。