Home > Enterprise >  Choosing An Image From Gallery And Display Into ImageView into Different VC - Swift
Choosing An Image From Gallery And Display Into ImageView into Different VC - Swift

Time:11-22

Not too sure why but I have run into an issue. Essentially, I have a button in one VC which opens an action sheet. Once a user chooses a picture from their library or takes a photo and chooses that, I wanted to navigate away from that VC, onto a new VC to display that picture chosen. However, I run into this issue at the bottom. It works when everything is in one VC, but I am assuming I am not passing the image correctly. Can anyone have a look, and suggest ways to make this work? Thanks!

Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let moreDetail = storyboard.instantiateViewController(identifier: "AddPostViewController") as! AddPostViewController
        
picker.dismiss(animated: true, completion: nil)
        
guard let selectedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage else {return}
  
moreDetail.postImage.image = selectedImage // error
        
self.navigationController?.pushViewController(moreDetail, animated: true)
          
} 

CodePudding user response:

Use below code :-

For First VC:--

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let moreDetail = storyboard.instantiateViewController(identifier: "AddPostViewController") as? AddPostViewController {


  picker.dismiss(animated: true) {
     
    guard let selectedImage = info[UIImagePickerController.InfoKey.editedImage] 
 as? UIImage else {return}
  
   moreDetail.img = selectedImage 
        
   self.navigationController?.pushViewController(moreDetail, animated: true)   
  }
          
 } 

}

For Second VC :-

class AddPostViewController: UIViewController {

@IBOutlet weak var postImage: UIImageView!
var img : UIImage ?

  override func viewDidLoad() {
        super.viewDidLoad()
        
     if let img = self.img  {
        self.postImage.image = img
    }
        

  }

}

CodePudding user response:

Most likely the postImage property of AddPostViewController isn't created yet at the time you try to assign the image.

This isn't the best design either. The first view controller shouldn't have any knowledge about the views of AddPostViewController (or any other view controller). The better solution is to add a UIImage property to AddPostViewController and have the first view controller assign to that property. Then let the implementation of AddPostViewController populate its image view with the image property when the time is right.

This provides a better separation of the MVC design. View controller one only needs to know about the model (UIImage) of the second controller. A given controller should be the only entity that knows how to connect the data to its views. This makes your code less fragile too. You may want to redesign the views around the same data. If no other class is trying to directly access the views then such a change is seamless.


Another possible issue is that you never properly setup the postImage outlet in the storyboard. If that's the case, after fixing that you should still consider the changes I describe above.

CodePudding user response:

I agree with HangarRash's answer.

You can add the UIImage property to the AddPostViewController and then whenever AddPostViewController is loaded set this UIImage property to UIImageView.

follow the below steps to achieve the results.

Step 1 :- create a property UIImage property in AddPostViewController.

var postImg : UImage?

Step 2 :- put the below code in didFinishPickingMediaWithInfo method.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let moreDetail = storyboard.instantiateViewController(identifier: "AddPostViewController") as! AddPostViewController
    picker.dismiss(animated: true, completion: nil)
    guard let selectedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage else {return}
    moreDetail.postImg = selectedImage 
    self.navigationController?.pushViewController(moreDetail, animated: true)
}

Step 3 :- set postImg in your viewDidLoad in AddPostViewController

if let img = postImg{
    postImage.image = img
}
  • Related