在UIImageView上使用TapGesture呈现图像选择器

时间:2017-10-07 06:34:04

标签: swift3 uiview uiviewcontroller uiimageview

我有一个UIImageView的视图,我想要'可选',以便用户可以选择一个新图像。

选择新图像的功能在Controller中。

问题

如何通过按myDatasourceController.handleTap()来调用ImageView功能,以便显示图像选择器?

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

视图

class myView: UICollectionViewCell {

    lazy var profileImageView: UIImageView = {
        let iv = UIImageView()
        iv.isUserInteractionEnabled = true
        iv.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(myDatasourceController.handleTap)))
        return iv
    }()
}

控制器

class myDatasourceController: UICollectionViewController, 
    UICollectionViewDelegateFlowLayout, UIImagePickerControllerDelegate, 
        UINavigationControllerDelegate {

    func handleTap(){

        let imagePickerController = UIImagePickerController()

        imagePickerController.delegate = self
        imagePickerController.allowsEditing = true

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

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

        // logic for picking the image

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

此设置当前会抛出错误

  

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

让我尝试了

的各种组合
handleTap(_:)
handleTap(sender: UITapGestureRecogniser)
/// etc

但我不能让他们中的任何一个工作。我应该如何构建我的视图,控制器以及它们之间的交互以呈现图像选择器?

3 个答案:

答案 0 :(得分:1)

像这样使用

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)
    }
}

答案 1 :(得分:0)

像这样使用:

myDatasourceController.handleTap()

在您的代码中:

iv.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(myDatasourceController.handleTap())))

答案 2 :(得分:0)

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

所示

我已将整个项目上传到my github account。密钥代码在这里复制。

查看控制器

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")
    }  
}