Swift3 在UIImageView上使用Tap手势显示图像选择器

Swift3 在UIImageView上使用Tap手势显示图像选择器,swift3,uiview,uiviewcontroller,uiimageview,Swift3,Uiview,Uiviewcontroller,Uiimageview,我有一个带有UIImageView的视图,我希望它是“可选择的”,以便用户可以选择一个新图像 用于拾取新图像的功能位于控制器中 问题 如何通过按ImageView调用myDatasourceController.handleTap()函数,以便显示图像选择器 这是我当前设置的一个示例 看法 控制器 此安装程序当前抛出错误 已将无法识别的选择器发送到实例0x7f9163d493f0 这让我尝试了不同的组合 handleTap(_:) handleTap(sender: UITapGestureR

我有一个带有
UIImageView
的视图,我希望它是“可选择的”,以便用户可以选择一个新图像

用于拾取新图像的功能位于控制器中

问题 如何通过按
ImageView
调用
myDatasourceController.handleTap()
函数,以便显示图像选择器

这是我当前设置的一个示例

看法 控制器
此安装程序当前抛出错误

已将无法识别的选择器发送到实例0x7f9163d493f0

这让我尝试了不同的组合

handleTap(_:)
handleTap(sender: UITapGestureRecogniser)
/// etc
但是我不能让他们中的任何一个工作。我应该如何构建视图、控制器以及它们之间的交互来显示图像选择器?

使用如下方式:

myDatasourceController.handleTap()
在代码中:

iv.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(myDatasourceController.handleTap())))
像这样使用

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(RegisterViewController. handleTap(gesture:)))

func handleTap(gesture: UIGestureRecognizer) {
    // if the tapped view is a UIImageView then set it to imageview
    if (gesture.view as? UIImageView) != nil {
        print("Image Tapped")
        picker.allowsEditing = false
        picker.sourceType = .photoLibrary
        picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!

        present(picker, animated: true, completion: nil)
    }
}

解决方案的关键是实现@Akis建议的协议/委托

我已将整个项目上载到。密钥代码复制到这里

视图控制器 看法
这无法生成,错误为:
实例成员'handleTap'不能在类型'MyDatasourceController'上使用
这仍然会给发送到实例0x7fc025d47ff0'的
无法识别的选择器带来
错误请确保您仅以这种方式编写代码:-“handleTap(手势:)”您应该使用
Delegate
模式,而不是在视图类中直接引用VC。类似于
UITableView
。创建一个协议,当点击该协议时,视图将通知您。现在你的VC应该实现这个委托,并在点击imageview时获取事件。@Aks-是!谢谢你的指点。我已经发布了解决方案作为答案。
iv.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(myDatasourceController.handleTap())))
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(RegisterViewController. handleTap(gesture:)))

func handleTap(gesture: UIGestureRecognizer) {
    // if the tapped view is a UIImageView then set it to imageview
    if (gesture.view as? UIImageView) != nil {
        print("Image Tapped")
        picker.allowsEditing = false
        picker.sourceType = .photoLibrary
        picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!

        present(picker, animated: true, completion: nil)
    }
}
protocol ImagePickerDelegate: class {
    func loadImagePicker()
}

class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UIImagePickerControllerDelegate, UINavigationControllerDelegate, ImagePickerDelegate {

    let cellId = "cellId"

    func loadImagePicker(){
        print(" -- image picker -- ")
        // load image picker

        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.allowsEditing = true

        present(imagePickerController, animated: true, completion: nil)
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        // get the image
        var selectedImageFromPicker: UIImage?

        if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
            selectedImageFromPicker = editedImage
        }else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
            selectedImageFromPicker = originalImage
        }

        if let selectedImage = selectedImageFromPicker {
            //doSomethingWithTheImage(image: selectedImage)
        }
        dismiss(animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView?.backgroundColor = .black
        collectionView?.register(HomeView.self, forCellWithReuseIdentifier: cellId)
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 1
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! HomeView
        cell.delegate = self
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: view.frame.height)
    }
}
class HomeView: UICollectionViewCell {

    // break retain cycle with weak var
    weak var delegate: ImagePickerDelegate?

    override init(frame: CGRect) {
        super.init(frame: frame)      
        setupViews()
    }

    lazy var profileImageView: UIImageView = {
        let iv = UIImageView()
        iv.isUserInteractionEnabled = true
        iv.image = UIImage(named: "kuang-si-falls-waterfall-water-laos-50588.jpg")
        iv.contentMode = .scaleAspectFill
        let tap = UITapGestureRecognizer(target: self, action: #selector(loadImagePicker))
        iv.addGestureRecognizer(tap)
        return iv
    }()

    func loadImagePicker() {
        delegate?.loadImagePicker()
        print(" imagePickerProtocol called ")
     }

    func setupViews() {
        backgroundColor = .white

        addSubview(profileImageView)

        profileImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        profileImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        profileImageView.frame = CGRect(x: 0, y: 0, width: 150, height: 150)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }  
}