Как получить доступ к UIImageView из UITableViewCell в пользовательской функции из UIViewController

#ios #swift

#iOS #swift

Вопрос:

Я пытаюсь присвоить изображение (которое находится в UIViewController) UIImageView (которое находится в UITableViewCell), когда камера закрывается. Проблема в том, что я не могу получить доступ к своему UIViewController из ячейки в той функции, где мне это нужно. Где мне нужно настроить мой UIImageView, чтобы иметь доступ к нему в моей функции из UIViewController?

Я уже пытался использовать метод делегирования, чтобы передать мой UIImageView в UIViewController, а затем вызвать этот метод делегирования и назначить изображение. Но по некоторым причинам не работает.

Вот мой код из UITableViewCell:

 protocol DefectAndDamageCellDelegate {
    func receiveImageViewFromCell(imageView: UIImageView)
}

class DefectAndDamageCheckCell: UITableViewCell {

    // Interface Links
    @IBOutlet weak var defectImageView: UIImageView!

    // Properties
    var delegate: DefectAndDamageCellDelegate?

    override func awakeFromNib() {
        super.awakeFromNib()

    }

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

    }

    func configCell(){
        delegate?.receiveImageViewFromCell(imageView: defectImageView)
    }
}
  

Вот мой код из UIViewController:

 extension DefectAndDamageCheckVC: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: Constants.defectAndDamageCell, for: indexPath) as! DefectAndDamageCheckCell
        cell.configCell()
        cell.delegate = self
        return cell
    }
}

extension DefectAndDamageCheckVC: DefectAndDamageCellDelegate{

    func receiveImageViewFromCell(imageView: UIImageView) {

        print("Image loaded")
    }
}

extension DefectAndDamageCheckVC: UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    // Open camera when the user hold on a cell and choose Camera.
    func showCamera() {

        self.imagePicker =  UIImagePickerController()
        self.imagePicker.delegate = self
        self.imagePicker.sourceType = .camera
        present(self.imagePicker, animated: true, completion: nil)
    }

    //Dismiss the Camera and display the selected image into the UIImageView
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){
        imagePicker.dismiss(animated: true, completion: nil)
        guard let selectedImage = info[.originalImage] as? UIImage else {
            print("Image not found!")
            return
        }

        // How can I access the imageView from my Cell here ?
        //myImageViewFromCell.image = selectedImage // issue here


        // This delegate don't work for some reasons. When I debug I can see the image on 'selectedImage' but is not assigned to my UIImageView
        receiveImageViewFromCell(imageView: UIImageView(image: selectedImage)) 
    }

}

  

Вот небольшой пример GitHub с моей проблемой. Чтобы получить доступ к камере, вам нужно нажать на ячейку.
https://github.com/tygruletz/sendDataFromCellToController/

Спасибо!

Комментарии:

1. Такое ощущение, что вы двигаетесь по кругу.. из cellForRow в configCell и здесь вы вызвали делегатов, которые возвращаются к DefectAndDamageCheckVC.

Ответ №1:

Весь смысл в том, чтобы иметь некоторый массив источников данных

 var images = [UIImage]()
  

которая объявляет, сколько ячеек имеет ваше табличное представление

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return images.count
}
  

Затем с помощью этого источника данных вы можете сказать что-то вроде, если это ячейка в этом IndexPath , установите это изображение. Для этой цели вы можете легко получить доступ к UIImageView определенной ячейке в cellForRowAt , вам не нужен протокол делегирования

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: Constants.defectAndDamageCell, for: indexPath) as! DefectAndDamageCheckCell
    cell.defectImageView.image = images[indexPath.row]
    return cell
}
  

Итак, когда изображение выбрано UIImagePickerController , измените источник данных для вашего табличного представления (добавьте это новое изображение), а затем вставьте новую строку в табличное представление

 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){
    imagePicker.dismiss(animated: true, completion: nil)
    guard let selectedImage = info[.originalImage] as? UIImage else {
        print("Image not found!")
        return
    }

    images.append(selectedImage)
    tableView.insertRows(at: [IndexPath(row: images.count - 1, section: 0)], with: .automatic)
}
  

Комментарии:

1. Я реализую то, что вы мне сказали, но теперь в этой строке появляется ошибка: cell.defectImageView.image = images[indexPath.row] // Фатальная ошибка: индекс вне диапазона

2. @Flo не забудьте изменить numberOfRowsInSection метод источника данных, чтобы возвращать количество элементов внутри images массива

3. Я сделал и все еще сбой в том же месте.

4. @Flo когда вы получаете эту ошибку? Когда вы запускаете свое приложение?

5. Да, Роберт. При запуске моего приложения происходит сбой.