I am asking if it is possible to set the image of a UIImageView using a gestureRecognizer, or is it necessary to overlay a button on top of the UIImageView.
I have an outlet collection of UIImageViews, called imageViews. There are four of these, and their tags have been set from 1 to 4. In my viewDidLoad, to add the gesture recognizer to each of the image views in the collection, i have used:
override func viewDidLoad() {
super.viewDidLoad()
for i in (0..<imageViews.count) {
let imageViewTapped = UITapGestureRecognizer(target: self, action: #selector(selectImage(tap:)))
imageViewTapped.numberOfTapsRequired = 1
imageViews[i].addGestureRecognizer(imageViewTapped)
}
}
Next, I created my gestureRecognizer as a function in the viewController class. This is where the image picker controller is created and where the image view that was tapped is identified:
func selectImage(tap: UITapGestureRecognizer) {
var imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = false
imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
self.present(imagePicker, animated: true, completion: nil)
guard let viewTappedTag = tap.view?.tag else {return}
self.selectedImageView = imageViews[viewTappedTag - 1]
}
selectedImageView is a variable in the viewController class with a type of UIImageView. My thinking was that this variable could hold the UIImageView that was tapped, which is identified by the gestureRecognizer, as shown above. This could then be passed to the delegate later on.
Next, I created the delegates, the didFinishPickingMediaWithInfo and didCancel, though I will only show the former for brevity. Both were created inside the viewController class:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
self.selectedImageView.image = chosenImage
dismiss(animated: true, completion: nil)
}
Unfortunatley, the image of the image view that was tapped is not updated to the one that was chosen from the library. What is the correct way to do this? And I feel as though I am bloating my viewController with all of this code, can this be moved to a seperate class? Am i wrong in doing it like this, and instead one should just overlay a button?
EDIT
The best I could come up with so far is a switch statement in my imagePickerController, where imageViewOne, imageViewTwo etc are outlets for each UIImageView:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
switch self.viewTappedTag {
case 1:
imageViewOne.image = chosenImage
case 2:
imageViewTwo.image = chosenImage
case 3:
imageViewThree.image = chosenImage
case 4:
imageViewFour.image = chosenImage
default:
imageViewOne.image = chosenImage
}
dismiss(animated: true, completion: nil)
}
where viewTappedTag is a viewController class variable, the value of which is defined by the tag of the view that was tapped and is set in the gestureRecognizer. Can anyone improve on this?
In the end I used a switch statement to achieve my goal:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
switch self.viewTappedTag {
case 1:
imageViewOne.image = chosenImage
case 2:
imageViewTwo.image = chosenImage
case 3:
imageViewThree.image = chosenImage
case 4:
imageViewFour.image = chosenImage
default:
imageViewOne.image = chosenImage
}
dismiss(animated: true, completion: nil)
}