UIImagePickerController crashes with LongPressGesture - swift

Today I realized that my UIImagePickerController is working fine when I use it with a button to present it. However, when I want to present it via LongPressGesture, the app crashes on runtime. Why so?
Action:
#IBAction func ppLongPressed(_ sender: UILongPressGestureRecognizer) {
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
present(imagePicker, animated: true, completion: nil)
}
Delegate:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
self.profileImage.image = image
}
dismiss(animated: true, completion: nil)
}

The long gesture has states
#IBAction func ppLongPressed(_ sender: UILongPressGestureRecognizer) {
if sender.state != .began { return }
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
present(imagePicker, animated: true, completion: nil)
}

Related

How to add 2 or more images into email from photo gallery to MFMailComposeViewController [duplicate]

I am making an app in which there are two UIImageViews. In each image view the user needs to be able to input a different image. Here is the code I have so far.
var imagePicker = UIImagePickerController()
#IBAction func chooseImage1(sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.SavedPhotosAlbum){
println("Button capture")
imagePicker.delegate = self
imagePicker.sourceType = .SavedPhotosAlbum
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
#IBAction func chooseImage2(sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.SavedPhotosAlbum){
println("Button capture")
imagePicker2.delegate = self
imagePicker2.sourceType = .SavedPhotosAlbum
imagePicker2.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
chooseImage1.image = pickedImage
let pickedImage2 = info[UIImagePickerControllerOriginalImage] as? UIImage
chooseImage2.image = pickedImage2
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
This ends up picking the same image for each different image view. I would like to be able to choose two individual photos, one for each view. Thank you for your help.
You only need one UIImagePickerController. You can keep a reference of the tapped view and when the user finish picking the image, you just need to cast the selected view as UIImageView and set its image property:
update: Xcode 11.5 • Swift 5.2 or later
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate ,UINavigationControllerDelegate {
#IBOutlet weak var imageView1: UIImageView!
#IBOutlet weak var imageView2: UIImageView!
var imagePicker = UIImagePickerController()
var selectedVew: UIView!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
imagePicker.sourceType = .savedPhotosAlbum
imagePicker.allowsEditing = false
[imageView1,imageView2].forEach {
$0?.isUserInteractionEnabled = true
$0?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(chooseImage)))
}
}
#objc func chooseImage(_ gesture: UITapGestureRecognizer) {
if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum) {
selectedVew = gesture.view
present(imagePicker, animated: true)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
(selectedVew as? UIImageView)?.image = info[.originalImage] as? UIImage
dismiss(animated: true)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true)
}
}

UIImagePickerController Function Not Working Correctly for Camera, Works for Photo Album

I'm writing a function to add an image to a UIImageView with UIImagePickerController. Once the image is added, a Share button is then enabled - both the camera and the photo-album let me pick an image and add it to the UIImageView, but the share button is only enabled when I pick an image from the Photo Album. When I pick an image from the Camera, the button doesn't work. Any idea why? Here is the relevant code:
//Pick Image from Album
#IBAction func pickAnImageFromAlbum(_ sender: Any) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = .photoLibrary
pickerController.allowsEditing = true
present(pickerController, animated: true, completion: nil)
}
//Pick Image from Camera
#IBAction func pickAnImageFromCamera(_ sender: Any) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = .camera
pickerController.allowsEditing = true
present(pickerController, animated: true, completion: nil)
}
//Send image to UIImageViewer, enable Share Button
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.editedImage] as? UIImage {
shareButton.isEnabled = true
imageViewer.image = image
}
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}

image not show in uiimageview

i want to get image from library but, image not show until I choose from library
this is my code
#IBAction func btnProfile(_ sender: UIButton) {
let alert = UIAlertController(title: "Change Profil Image", message: "Pilih Foto", preferredStyle: UIAlertControllerStyle.actionSheet)
alert.addAction(UIAlertAction(title: "Gunakan Kamera", style: .default, handler: { (action: UIAlertAction!) in
print("Gunakan Kamera")
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.camera;
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Ambil Foto dari Galery", style: .default, handler: { (action: UIAlertAction!) in
print("Ambil Foto dari Galery")
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary;
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in
print("Cancel")
}))
present(alert, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[.originalImage] as? UIImage else { return } // error in here >> 'UIImage?' is not convertible to 'UIImage' >> and warning yellow >> Cast from 'Slice<Dictionary<UIImagePickerController.InfoKey, Any>>' (aka 'Slice<Dictionary<NSString, Any>>') to unrelated type 'UIImage' always fails
picker.dismiss(animated: true, completion: nil)
imgProf.image = image
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
I want to display the image on UIimageview, but after I retrieve it from the library it doesn't always appear,
error in guard let image, and warning yellow in there
i use swift 3
this is UIImagePickerControllerDelegate
public protocol UIImagePickerControllerDelegate : NSObjectProtocol {
#available(iOS 2.0, *)
optional public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
#available(iOS 2.0, *)
optional public func imagePickerControllerDidCancel(_ picker: UIImagePickerController)
}
I tried this code and it worked
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
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 {
imgProf.image = selectedImage
}
dismiss(animated: true, completion: nil)
}
and thanks for #Kamran, your answer for change the position is true
self.present(imagePicker, animated: true, completion: {
imagePicker.delegate = self
})
Set picker delegate in completion.

Why doesn't my View disappear after removing from parent ViewController in Swift?

I am making an app using sprite kit, so my scenes/views are all SKView optionals. However I am trying to allow the user to upload/take photos, and everything works well on that end. However, after the user selects a photo, my image view controller somehow gets animated again, and the scene that I was in before no longer enables interaction, so it is basically frozen. I am confused why this happens... this is what I have tried so far:
Scene that I am in when giving option for selecting a photo
func photoToController(sender: UIButton){
var button = sender
let controller = imageViewController()
sender.superview?.removeFromSuperview()
view?.addSubview(controller.view)
controller.pickPhoto(sender: &image, button: &imageUploader, buttonsender: &button)
}
ViewController that allows user to deal with photo library/camera
class imageViewController : UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var image = UIImageView()
var Abutton = UIButton()
var takingPhoto = false
override func viewDidLoad() {
print("imgviewloaded")
}
override func viewDidAppear(_ animated: Bool) {
print("image view is animated")
}
func pickPhoto(sender: inout UIImageView, button: inout UIButton, buttonsender: inout UIButton) {
let types = [UIImagePickerControllerSourceType.photoLibrary,UIImagePickerControllerSourceType.camera]
if UIImagePickerController.isSourceTypeAvailable(types[buttonsender.tag]) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = types[buttonsender.tag]
if buttonsender.tag == 1 {takingPhoto = true
imagePicker.allowsEditing = false
} else {
imagePicker.allowsEditing = true
}
image = sender
Abutton = button
self.present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
self.removeFromParentViewController()
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
if takingPhoto{image.contentMode = .scaleToFill}
if image.image == info[UIImagePickerControllerOriginalImage] as? UIImage{
savedPhotos.saveNewPhoto(newPhoto : image.image!)
}
image.backgroundColor = UIColor.white
Abutton.setTitle("", for: .normal)
picker.dismiss(animated: true, completion: nil)
self.removeFromParentViewController()
}
}

my segue is not working in imagepicker

I have an UIImagePickerController so when user choose his/her photo the segue is performed but segue is not working ( actually is working but the vc is not loaded ) this is my code:
let imagepicker = UIImagePickerController()
imagepicker.delegate = self
imagepicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagepicker.allowsEditing = true
self.present(imagepicker, animated: true)
//...
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
takenimage = info[UIImagePickerControllerOriginalImage] as! UIImage
self.dismiss(animated: true, completion: nil)
print("image loaded")
performSegue(withIdentifier: "ToPrescriptionView", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ToPrescriptionView" {
let PrescriptionView = segue.destination as! Prescription
PrescriptionView.PrescriptionImage = takenimage
print("segue loaded")
}
I'm getting "image loaded" and "segue loaded" but my viewcontroller remains previous one
Try to performSegue inside completion block of dismiss when you dismissing UIImagePickerController.
self.dismiss(animated: true) {
performSegue(withIdentifier: "ToPrescriptionView", sender: nil)
}