user5619350
user5619350

Reputation:

How to run imagePicker in tableViewCell

I have a tableView with a cell. In this cell I have an imageView, and a button covering it. The button has an IBAction. When tapped, the button is supposed to summon the imagePicker. The IBAction code is located in the cell subview.

@IBAction func MyStatusImageButtonAction(sender: AnyObject) {
    // Select Image
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
    imagePicker.allowsEditing = false
    self.presentViewController(imagePicker, animated: true, completion: nil)

I get an error because of this line.

self.presentViewController(imagePicker, animated: true, completion: nil)

Error says "Value of type "myCell" has no member "presentViewController".

Am I supposed to load the imagePicker in the viewController that hosts the cell, then transfer it to the cell somehow? Am I supposed to load the imagePicker in the cell with different code? Am I going about this all wrong?

For clarity, my goal is for the user to load this TableViewController, and have the ability to assign an image to the imageView in this cell only.

Thank you.

Upvotes: 5

Views: 3738

Answers (4)

Yorzic
Yorzic

Reputation: 122

Just a follow up on @truongky's post with updated syntax for Swift 5.

As he correctly points out, first create a protocol. You can create a new file with extension for your protocols. Then insert the code that the OP identified:

protocol ImagePickerDelegate {
    func pickImage() 
}


Then, in your TableViewController:

func pickImage() {
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
    imagePicker.allowsEditing = false
    self.present(imagePicker, animated: true, completion: nil)
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
        let cell:ImageCell = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as! ImageCell
        cell.customImage.image = image
    }

    picker.dismiss(animated: true, completion: nil)
}


In addition, you can modify your custom cell to respond to a tap gesture recognizer as so:

var delegate : ImagePickerDelegate?

@IBOutlet weak var customImage: UIImageView!

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code

    addTapGestureRecognizer(for: customImage)
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

func addTapGestureRecognizer(for view: UIImageView) {
    let tap = UITapGestureRecognizer(target: self, action: #selector(pickImage))
    tap.numberOfTapsRequired = 1
    view.isUserInteractionEnabled = true
    view.addGestureRecognizer(tap)
}

@objc func pickImage() {
    delegate?.pickImage()
}


Hope this helps.

Kudos~

Upvotes: 1

user5619350
user5619350

Reputation:

I found a very comprehensive step by step answer here

https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson6.html#//apple_ref/doc/uid/TP40015214-CH20-SW1

Start at "Define your data model".

Basically what happens is that you define your data in a Swift file. Then you set the photo equal to ImageView in the ViewController. Then still in the ViewController code, you point the newly defined photo to your cell. I had been tackling the problem all wrong. The link provided is very comprehensive.

Upvotes: 0

truongky
truongky

Reputation: 1147

Write a protocol and your TableViewController will show it for you.

protocol ImagePickerDelegate {

    func pickImage()
}

In your cell

var delegate : ImagePickerDelegate?

@IBAction func pickImage(sender: AnyObject) {

    delegate?.pickImage()
}

In your tableViewController

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("displayImage", forIndexPath: indexPath) as! ImageTableViewCell

    cell.delegate = self

    return cell
}

func pickImage() {

    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
    imagePicker.allowsEditing = false
    self.presentViewController(imagePicker, animated: true, completion: nil)
}

func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {

    dismissViewControllerAnimated(true, completion: nil)

    var cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0)) as! ImageTableViewCell
    cell.displayImageView.image = image
}

Hope this help.

Upvotes: 5

ShahiM
ShahiM

Reputation: 3268

only a viewController can present another viewController. So use :

self.view.presentViewController(imagePicker, animated: true, completion: nil)

Upvotes: 1

Related Questions