简体   繁体   中英

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.

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.

only a viewController can present another viewController . So use :

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

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.

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~

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM