Reputation: 13883
I made a view controller to show up an Image, the image will be shown up after the user press the right button item in the checkOutVC
like this
the image should be appear in the ReusableImageDisplayVC
like this
I send the image from checkOutVC
to ReusableImageDisplayVC
, the code I use for those view controller are below :
class CheckoutTVC: UITableViewController {
@IBAction func openImageBarButtonDidPressed(_ sender: Any) {
var displayedImage = UIImage()
let imagePath = "https://***.jpg"
let urlImage = URL(string: imagePath)
NetworkingService.fetchData(url: urlImage!) { (result) in
self.activityIndicator.startAnimating()
switch result {
case .failure(let error) :
self.activityIndicator.stopAnimating()
self.showAlert(alertTitle: "Sorry", alertMessage: error.localizedDescription, actionTitle: "Back")
case .success (let imageData):
self.activityIndicator.stopAnimating()
displayedImage = UIImage(data: imageData)!
}
}
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let popup = storyboard.instantiateViewController(withIdentifier: "imageDisplay") as! ReusableImageDisplayVC
popup.photo = displayedImage
present(popup, animated: true, completion: nil)
}
}
and the code in ReusableImageDisplayVC are below
class ReusableImageDisplayVC: UIViewController {
@IBOutlet weak var ImagePhoto: UIImageView!
var photo : UIImage?
override func viewDidLoad() {
super.viewDidLoad()
if photo == nil {
print("photo is nil")
} else {
print("photo is not nil")
}
print(photo!)
ImagePhoto.image = photo!
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ReusableImageDisplayVC.tapFunction(sender:)))
tapGesture.numberOfTapsRequired = 1
ImagePhoto.addGestureRecognizer(tapGesture)
view.addGestureRecognizer(tapGesture)
}
@objc func tapFunction(sender: UITapGestureRecognizer) {
dismiss(animated: true, completion: nil)
}
}
as we can see in the ReusableImageDisplayVC
I am trying to make sure that the UIImage from previous VC is available, and in the debugging area it is printed
photo is not nil, UIImage: 0x6040008bde20, {0, 0}
I have also assigned to the ImageView ImagePhoto.image = photo!
but why when I run the app, it doesn't appear?
but if I hard code the downloading image process stright in the ReusableImageDisplayVC like the code below, the image will appear
class ReusableImageDisplayVC: UIViewController {
@IBOutlet weak var ImagePhoto: UIImageView!
var photo : UIImage?
var something : String?
override func viewDidLoad() {
super.viewDidLoad()
let imagePath = "https://***.jpg"
let urlImage = URL(string: imagePath)
NetworkingService.fetchData(url: urlImage!) { (result) in
switch result {
case .failure(let error) :
self.showAlert(alertTitle: "Sorry", alertMessage: error.localizedDescription, actionTitle: "Back")
case .success (let imageData):
self.ImagePhoto.image = UIImage(data: imageData)!
}
}
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ReusableImageDisplayVC.tapFunction(sender:)))
tapGesture.numberOfTapsRequired = 1
ImagePhoto.addGestureRecognizer(tapGesture)
view.addGestureRecognizer(tapGesture)
}
@objc func tapFunction(sender: UITapGestureRecognizer) {
dismiss(animated: true, completion: nil)
}
}
what went wrong in here?
Upvotes: 1
Views: 182
Reputation: 13771
displayedImage
isn't set yet when you present the ReusableImageDisplayVC
view controller. This is because you're presenting the view controller before the async call is finished. Try this instead:
@IBAction func openImageBarButtonDidPressed(_ sender: Any) {
NetworkingService.fetchData(url: urlImage!) { [weak self] (result) in
var displayedImage = UIImage()
let imagePath = "https://example.com/someimage.jpg"
let urlImage = URL(string: imagePath)
self?.activityIndicator.startAnimating()
switch result {
case .failure(let error) :
self?.activityIndicator.stopAnimating()
self?.showAlert(alertTitle: "Sorry", alertMessage: error.localizedDescription, actionTitle: "Back")
return //return instead of presenting ReusableImageDisplayVC
case .success (let imageData):
self?.activityIndicator.stopAnimating()
displayedImage = UIImage(data: imageData)!
}
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let popup = storyboard.instantiateViewController(withIdentifier: "imageDisplay") as! ReusableImageDisplayVC
popup.photo = displayedImage
self?.present(popup, animated: true, completion: nil)
}
}
(note the use of [weak self]
, self?
, and return
in the fetchData
completion handler)
Upvotes: 3