0

The following code allows the user to select an image from the gallery or to take a picture and displays it within the ViewController via ImageView. What I want to do here is to pass the image that was taken or selected from the gallery and pass it to another ViewController to which it gets displayed in an ImageView. Ideally once the picture is selected or taken the ViewController changes immediately to the Second ViewController and displays the image in the ImageView.

How can this be achieved? thanks.

import Foundation
import UIKit
import MobileCoreServices
import AssetsLibrary
import AVFoundation
import SystemConfiguration

class ViewController: UIViewController, UITextViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, UIPopoverControllerDelegate, UIAlertViewDelegate {

    var controller = UIImagePickerController()
    var assetsLibrary = ALAssetsLibrary()
    var selectedImage = UIImageView ()

    private var image: UIImage? // THIS ONE

    @IBOutlet weak var btnClickMe: UIButton!
    @IBOutlet weak var imageView: UIImageView!

    var picker:UIImagePickerController?=UIImagePickerController()
    var popover:UIPopoverController?=nil

    override func viewDidLoad() {
        super.viewDidLoad()
        picker!.delegate=self

    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }

    @IBAction func btnImagePickerClicked(sender: AnyObject)
    {
        let alert:UIAlertController=UIAlertController(title: "Choose Image", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)

        let cameraAction = UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default)
            {
                UIAlertAction in
                self.openCamera()

        }
        let gallaryAction = UIAlertAction(title: "Gallery", style: UIAlertActionStyle.Default)
            {
                UIAlertAction in
                self.openGallary()
        }
        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel)
            {
                UIAlertAction in

        }

        // Add the actions
        picker?.delegate = self
        alert.addAction(cameraAction)
        alert.addAction(gallaryAction)
        alert.addAction(cancelAction)
        // Present the controller
        if UIDevice.currentDevice().userInterfaceIdiom == .Phone
        {
            self.presentViewController(alert, animated: true, completion: nil)
        }
        else
        {
            popover=UIPopoverController(contentViewController: alert)
            popover!.presentPopoverFromRect(btnClickMe.frame, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
        }
    }
    func openCamera()
    {
        if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
        {
            picker!.sourceType = UIImagePickerControllerSourceType.Camera
            self .presentViewController(picker!, animated: true, completion: nil)
        }
        else
        {
            openGallary()
        }
    }
    func openGallary()
    {
        picker!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
        if UIDevice.currentDevice().userInterfaceIdiom == .Phone
        {
            self.presentViewController(picker!, animated: true, completion: nil)
        }
        else
        {
            popover=UIPopoverController(contentViewController: picker!)
            popover!.presentPopoverFromRect(btnClickMe.frame, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
        }
    }
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
    {
        picker .dismissViewControllerAnimated(true, completion: nil)
        imageView.image=info[UIImagePickerControllerOriginalImage] as? UIImage
        image = imageView.image!
        performSegueWithIdentifier("TEST", sender: self)
    }
    func imagePickerControllerDidCancel(picker: UIImagePickerController)
    {
        print("picker cancel.")

    }
}

Here is my second ViewController

 import UIKit

class ViewController2: UIViewController {

        var Image = UIImage ()

        @IBOutlet var imageView: UIImageView!

        override func viewDidLoad() {
            super.viewDidLoad()
            imageView.image = Image
        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    }

2 Answers2

2

Edit 2

Given that you have too many mistakes in your code, I'm going to a bit more specific.

First: You need to understand the difference between UIImage and UIImageView

Second: If you want to perform segue after the user selects an image, you should call the method on the didFinishPickingMediaWithInfo delegate, like this:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
    picker .dismissViewControllerAnimated(true, completion: nil)
    imageView.image=info[UIImagePickerControllerOriginalImage] as? UIImage
    image = imageView.image!
    performSegueWithIdentifier("mySegueToNextViewController", sender: self)
}

Also, I added a new property called "image" (should be called "selectedImage", but you can change it later).

private var image: UIImage? // THIS ONE

@IBOutlet weak var btnClickMe: UIButton!
@IBOutlet weak var imageView: UIImageView!

Third: On the ViewController2 you need to set the image library to the UIImageView.

override func viewDidLoad() {
    super.viewDidLoad()
    imageView.image = selectedImage
}

Finally: In the Storyboard, select ViewController, go to editor -> Embed In -> Navigation Controller.

Now, should work just fine.


Once you select the image, call the following method:

performSegueWithIdentifier("mySegueToNextViewController", sender: self)

Then you need to implement:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "mySegueToNextViewController" {
        if let nextViewController = segue.destinationViewController as? NextViewController {

            nextViewController.image = selectedImage   
        }
    }

}

Keep in mind that for this to work, you should have public property on NextViewController (just like Unis Barakat said). Then on the NextViewController viewDidLoad() you could set the image to the imageView.

Hope this helps!

dmlebron
  • 861
  • 6
  • 16
  • I have updated the question and the code. I implemented the code that you suggested and still cannot get it to work. When I select an image or take an image the ViewController does not change to the second one nor does the image appear in the second view controller in the ImageView. I have set up the identifier correctly but still no luck. – Gurvier Singh Dhillon Jan 26 '16 at 19:24
  • Your mistake is that you are creating an IBOutlet of UIImage instead of UIImageView. `@IBOutlet var image: UIImage!` when it should be `@IBOutlet var imageView: UIImageView!`. Also in the `override func viewDidLoad()` you need to set the image property of the UIImageView like this. `imageView.image = selectedImage`. – dmlebron Jan 26 '16 at 19:58
  • @dave I have done the that but still no luck, the segue does not initialise hence why it does not switch views. I have set everything up correctly and have updated the code above. I will send you a download link. – Gurvier Singh Dhillon Jan 26 '16 at 20:11
  • Here is the the download link to the test version, which shows how its not working properly http://www.gamefront.com/files/25453575/TEST.zip – Gurvier Singh Dhillon Jan 26 '16 at 20:26
  • You want to as soon as the user select the image, move to the next view controller? – dmlebron Jan 26 '16 at 20:42
  • Yes thats right, once the user has selected their image, I want it to automatically change to the next view controller and display the image within the ImageView on the second ViewController. – Gurvier Singh Dhillon Jan 26 '16 at 20:44
  • I have followed what you have said and put everything in correctly, however once the image is selected the application still crashes, I have set up the Identifier correctly but still crashes. It crashes when it attempts to switch to the next ViewController and I think its something to do with the ImageView on the second ViewController. I have updated the code in my question, could you check where I am going wrong? thanks appreciate it. – Gurvier Singh Dhillon Jan 26 '16 at 22:54
  • Just delete from storyBoard ViewController2 view and a new one. Also, on top of the ViewController2 the UIImageView property is missing "weak" `@IBOutlet weak var imageView: UIImageView!'. Just do this and it should work (worked on the project you sent). – dmlebron Jan 27 '16 at 02:50
  • What do you mean by deleting from storyboard ViewController2 and a new one? – Gurvier Singh Dhillon Jan 27 '16 at 17:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/101804/discussion-between-dava-and-gurvier-singh-dhillon). – dmlebron Jan 27 '16 at 18:01
  • I have entered the chat and here is the test application, for some reason once the image is selected, the View changes to the next one but does not display the image within the image view. http://www.gamefront.com/files/25455266/TEST.zip – Gurvier Singh Dhillon Jan 27 '16 at 18:18
  • Just recreate the storyboard. Then add your sub classes to the UIViewControllers and connect the IBOutlets (remember IBOutlet are weak var). – dmlebron Jan 27 '16 at 18:33
  • I have done all of that, still not working, can you please have a look at my test project. I have recreated the storyboard and connected everything back and made sure IBOutlet are weak var. The problem that I am getting now is that once the image is selected the ViewController changes to the next one but is still blank and does not display the image. Would you mind sending me your working test project please thanks. – Gurvier Singh Dhillon Jan 27 '16 at 19:08
  • Keep in mind that we don't ask questions here to make someone else do what we are intending to do, we ask here to learn how to do it ourselves. I assume you are new to iOS programming and as newbie is very helpful to receive a little extra help from time to time. You were missing a lot of things. I just added the minimum basic stuff to make it work. Here is the link: https://www.dropbox.com/s/o6q11oxpoa4gxwj/TEST.zip?dl=0 – dmlebron Jan 29 '16 at 00:16
  • Thanks for your help and patience. I am new to IOS programming but on a final note is their a way to do this without the navigation controller or is that essential? Reason I ask is that I have another project and don't want the navigation bar appearing at the top. – Gurvier Singh Dhillon Jan 29 '16 at 00:36
  • There's lots of ways. But this is the simplest one. You can go ahead and verify if 'prepareForSegue' gets called even if the view controller is not embedded in a navigation controller. And good luck in your projects! – dmlebron Jan 29 '16 at 03:12
  • I tried deleting the navigation controller and testing it, it does not move to the next view nor does it display the image. ill have to figure it out but thanks again for your help and support. I have marked this question as answered now, if you have any other guidance about getting it working without the navigation controller it would be much appreciated. – Gurvier Singh Dhillon Jan 29 '16 at 16:14
  • @dava hey can you help me to solve this question https://stackoverflow.com/questions/47629344/how-to-fetch-image-and-pdf-file-from-json-and-display-in-tableviewcell-swift-3 your help would be really appreciated. thanks dude in advance – deltami Dec 13 '17 at 07:43
0

on top of class define a variable, something like:

var selectedImage: UIImage

then when you are in that view controller set that image and in the other view controller, you simply display the image that you set in the first controller.

Unis Barakat
  • 876
  • 1
  • 8
  • 23
  • global variables are poor design choices, if you're going to use a global you should at least do so by using a singleton. – Dan Beaulieu Jan 26 '16 at 18:28