My imagePickerController didFinishPickingMediaWithInfo newer get called - ios

I try to write an App that needs a screen where you can take multible photos. I have used a code example from http://makeapppie.com/2015/11/04/how-to-make-xib-based-custom-uiimagepickercontroller-cameras-in-swift/.
It seems to be working OK, but my imagePickerController didFinishPickingMediaWithInfo newer get called. I am getting an error message from Xcode "Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates." It sounds to me like this could be the problem, and I have googled it, but havn't gotten any wiser. A lot of people write it's an Apple bug and I havn't found anybody offering a solution.
So do anybody know if it is the Xcode error that is my problem, and in that case have a solution for that or have I written something wrong in my code:
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, CustomOverlayDelegate {
var picker = UIImagePickerController()
#IBAction func shootPhoto(sender: AnyObject) {
if UIImagePickerController.availableCaptureModesForCameraDevice(.Rear) != nil {
picker = UIImagePickerController() //make a clean controller
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.Camera
picker.cameraCaptureMode = .Photo
picker.showsCameraControls = false
//customView stuff
let customViewController = CustomOverlayViewController(
nibName:"CustomOverlayViewController",
bundle: nil
)
let customView:CustomOverlayView = customViewController.view as! CustomOverlayView
customView.frame = self.picker.view.frame
customView.cameraLabel.text = "Hello Cute Camera"
customView.delegate = self
//presentation of the camera
picker.modalPresentationStyle = .FullScreen
presentViewController(picker, animated: true,completion: {
self.picker.cameraOverlayView = customView
})
} else { //no camera found -- alert the user.
let alertVC = UIAlertController(
title: "No Camera",
message: "Sorry, this device has no camera",
preferredStyle: .Alert)
let okAction = UIAlertAction(
title: "OK",
style:.Default,
handler: nil)
alertVC.addAction(okAction)
presentViewController(
alertVC,
animated: true,
completion: nil)
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
print("didFinishPickingMediaWithInfo")
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage //get the image from info
UIImageWriteToSavedPhotosAlbum(chosenImage, self,nil, nil) //save to the photo library
}
//What to do if the image picker cancels.
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
//MARK: Custom View Delegates
func didCancel(overlayView:CustomOverlayView) {
picker.dismissViewControllerAnimated(true, completion: nil)
print("dismissed!!")
}
func didShoot(overlayView:CustomOverlayView) {
picker.takePicture()
overlayView.cameraLabel.text = "Shot Photo"
print("Shot Photo")
}
func weAreDone(overlayView: CustomOverlayView) {
picker.dismissViewControllerAnimated(true,
completion: nil)
print("We are done!")
}
}

Write
picker.delegate = self after
picker = UIImagePickerController() line
Also inherit you class with UIImagePickerControllerDelegate delegate.
It will work.

Related

didFinishPickingMediaWithInfo is not calling in Xcode 12

I already worked on UIImagePickerController. This code was already works fine in Xcode 11.3. But when I run on Xcode 12 Image picker delegate is not calling in Xcode12.
/// Picked Image
struct PickedImage {
var image: UIImage?
var api: String?
}
/// Image picker
class ImagePicker: NSObject {
typealias ImagePickerHandler = ((_ selected: PickedImage) -> ())
private weak var presentationController: UIViewController?
let pickerController: UIImagePickerController = UIImagePickerController()
var apiKey: String?
private var handler: ImagePickerHandler? = nil
private func action(for type: UIImagePickerController.SourceType, title: String) -> UIAlertAction? {
guard UIImagePickerController.isSourceTypeAvailable(type) else {
return nil
}
return UIAlertAction(title: title, style: .default) { (action) in
DispatchQueue.main.async {
self.pickerController.mediaTypes = ["public.image"]
self.pickerController.sourceType = type
self.pickerController.delegate = self
self.presentationController?.present(self.pickerController, animated: true, completion: {
})
}
}
}
/// Present source view
/// - Parameter sourceView: view
func present(presentationController: UIViewController, completed: ImagePickerHandler? = nil) {
self.handler = completed
self.presentationController = presentationController
// self.delegate = delegate
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
if let action = self.action(for: .camera, title: "Take photo") {
alertController.addAction(action)
}
if let action = self.action(for: .savedPhotosAlbum, title: "Camera roll") {
alertController.addAction(action)
}
if let action = self.action(for: .photoLibrary, title: "Photo library") {
alertController.addAction(action)
}
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
// if UIDevice.current.userInterfaceIdiom == .pad {
// alertController.popoverPresentationController?.sourceView = sourceView
// alertController.popoverPresentationController?.sourceRect = sourceView.bounds
// alertController.popoverPresentationController?.permittedArrowDirections = [.down, .up]
// }
self.presentationController?.present(alertController, animated: true)
}
private func pickerController(didSelect image: UIImage?, imageURL: URL?) {
pickerController.dismiss(animated: true, completion: nil)
// self.delegate?.imagePicker(picker: self, didSelected: image, apikey: apiKey)
handler?(PickedImage(image: image, api: apiKey))
}
}
/// ImagePicker controller delegate
extension ImagePicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.pickerController(didSelect: nil, imageURL: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
self.pickerController(didSelect: info[.originalImage] as? UIImage, imageURL: info[.imageURL] as? URL)
}
}
When I check delegate is applied or not using breakpoint. like in console means
po imagepicker.delegate
there after image picker delegate was working fine. But when I remove breakpoint its delegate is not calling.
I don't know what is the reason. Why its not working. May I know how to fix this problem.
is there any reason to not put pickerController.delegate = self before self.presentationController?.present(pickerController, animated: true, completion: {})'?
if no, maybe you can put pickerController.delegate = self before that, and try again.
This is most likely because you're not retaining your picker controller in a variable. As soon as your function finishes, it gets deallocated.
For example I have something like this:
class MyClass: UIImagePickerControllerDelegate {
let imagePicker = UIImagePickerController()
}
func pickImageFromGallery() {
self.imagePicker.delegate = self
self.imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
self.imagePicker.allowsEditing = false
self.present(self.imagePicker, animated: true, completion: nil)
}
... and the delegate methods as well
You code was always wrong; it's just lucky if it ever worked:
let pickerController: UIImagePickerController = UIImagePickerController()
pickerController.mediaTypes = ["public.image"]
pickerController.sourceType = "Photo library"
self.presentationController?.present(pickerController, animated: true, completion: {
pickerController.delegate = self
})
Change to:
let pickerController: UIImagePickerController = UIImagePickerController()
pickerController.mediaTypes = ["public.image"]
pickerController.sourceType = .photoLibrary
pickerController.delegate = self
self.present(pickerController, animated: true)
I think you are doing a silly mistake. just change a few lines of code and then you are good to go.
just follow my Steps
=> Here ProfileViewController is my UIViewController where I am going to pick Image from Gallery and Set image to UIImageView. You have to use your UIViewController where you want to Pick an Image.
ProfileViewController: UIViewController{
let pickerController = UIImagePickerController()
viewDidLoad(){
}
#IBAction func pickImageAction(sender: UIButton){
self.openImagePicker()
}
func openImagePicker()
{
pickerController.delegate = self
pickerController.allowsEditing = true
pickerController.mediaTypes = ["public.image", "public.movie"]
pickerController.sourceType = .photoLibrary // Pick image from PhotoLibrary
//pickerController.sourceType = .savedPhotosAlbum // Pick Saved Images
//pickerController.sourceType = .camera // Click Image using Camera
self.present(pickerController, animated: true)
} //End of setupImagePicker
} // End of ProfileViewController
// MARK:- Delegate method for UIImagePicker
extension ProfileViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[.editedImage] as? UIImage else { return }
// image is your image which you picked from Image Gallery or using Camera.
// you can set this image directly to your UIImageView.
// self.yourImageView.image = image
// or you can compress this image, converting to JPG image type.
// compressionQuality will reduce your image quality and Image Size.
if let jpegData = image.jpegData(compressionQuality: 0.8) {
// you can use this compressed image.
}
self.dismiss(animated: true)
}// End of didFinishPickingMediaWithInfo
} // End of Extension

white screen after present an UIImagePickerController

I'm presenting an UIImagePickerController to take a photo, the problem is if I take a photo, or cancel the UIImagePickerController I'll return on a white screen and not on my previous ViewController. Only my navigation bar still here. If I click to an other view (with the navigation bar) it's ok, and if I return on the tab where the UIImagePickerController is called it still white.
let picker = UIImagePickerController();
picker.delegate = self;
picker.mediaTypes = [swiftString];
picker.allowsEditing = true
picker.sourceType = UIImagePickerControllerSourceType.camera;
picker.cameraCaptureMode = .photo
self.present(picker, animated:true, completion:nil);
dismiss :
picker.dismiss(animated: true, completion:nil);
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion:nil);
}
If someone have an idea thank's !
Update :
White screen appears always when i call a view with present method. So i think it's conflict with the navigation controller (hierarchy...)
This solve my problem :
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
appDelegate.navigationController.present(picker, animated: true, completion: nil)
If someone have an other alternative to solve it !
Use picker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext before presenting the imagepicker.
Here's the code I use for the camera:
func openCameraApp() {
if UIImagePickerController.availableCaptureModes(for: .rear) != nil {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.camera
picker.cameraCaptureMode = .photo
picker.modalPresentationStyle = .fullScreen
present(picker,
animated: true,
completion: nil)
} else {
noCamera()
}
}
func noCamera(){
let alertVC = UIAlertController(
title: "No Camera",
message: "Sorry, this device has no camera",
preferredStyle: .alert)
let okAction = UIAlertAction(
title: "OK",
style:.default,
handler: nil)
alertVC.addAction(okAction)
present(
alertVC,
animated: true,
completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage // do you have this line in your code?
image = chosenImage
self.performSegue(withIdentifier: "ShowEditView", sender: self)
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: false, completion: nil)
}
I notice a couple of things different.
You set .allowsEditing to true. I don't believe that is making a difference.
I'm checking for a camera, but you probably didn't put that code in your question.
I'm setting .modalPresentationStyle to full screen. This could be your issue.
I don't see the imagePickerController(picker: didFinishPickingMediaWithInfo) call. But since it shouldn't build, that definitely isn't the issue.
Inside that call I unwrap the image from info. I believe this is your issue. I've placed a comment on that specific line, asking you to check for this.
Finally, I'm executing a segue to another view controller. (My app is basically a "select" then "edit".)
Set the .modalPresentationStyle to fullScreen

Type 'UIImagePickerControllerSourceType' has no member 'photoLibrary'

This is the code:
// Only allow photos to be picked,not taken.
imagePickerController.sourceType = .photoLibrary
this is the error: Type 'UIImagePickerControllerSourceType' has no member 'photoLibrary'
Just trying to complete the official tutorial Start Developing iOS Apps (Swift)
//MARK: Actions
#IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {
//Hide the keyboard.
nameTextField.resignFirstResponder()
// UIImagepickerController is a view controller that lets a user pick media from their photo library.
let imagePickerController = UIImagePickerController()
// Only allow photos to be picked,not taken.
imagePickerController.sourceType = .photoLibrary
//Make sure ViewController is notified when the user picks an image.
imagePickerController.delegate = self
present(imagePickerController, animated: true, competion: nil)
}
#IBAction func setDefaultLabelText(sender: UIButton) {
mealNameLabel.text = "Default Text"
}
}
Okay, it looks like you are probably usingSwift 2.2 (maybe it's this for Swift 2.3 also). You want this syntax:
imagePickerController.sourceType = .PhotoLibrary
Note the capitalization. Keep in mind, Xcode 8.2 (released 12 December 2016) will be the last version of Xcode to support Swift 2.x. Sometime in 2017 you will probably need to use Swift 3 for new App Store submissions.
EDIT:
Here's my full Swift 2.2 code, followed by my Swift 3.0 code. Please note two things:
I'm also using the Camera app and have checks to make sure it's present - which isn't the case for the simulator.
Your app will crash in iOS 10 unless you add the following to your info.plist file:
NSCameraUsageDescription
Used to capture new image for photo effect
NSPhotoLibraryUsageDescription
Used to select an image for photo effect
You may put different values in the tags.
Swift 2.2:
let picker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
}
extension SelectViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
// MARK: Camera App
func openCameraApp() {
if UIImagePickerController.availableCaptureModesForCameraDevice(.Rear) != nil {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.Camera
picker.cameraCaptureMode = .Photo
picker.modalPresentationStyle = .FullScreen
presentViewController(picker,
animated: true,
completion: nil)
} else {
noCamera()
}
}
func noCamera(){
let alertVC = UIAlertController(
title: "No Camera",
message: "Sorry, this device has no camera",
preferredStyle: .Alert)
let okAction = UIAlertAction(
title: "OK",
style:.Default,
handler: nil)
alertVC.addAction(okAction)
presentViewController(
alertVC,
animated: true,
completion: nil)
}
// MARK: Photos Albums
func showImagePicker() {
picker.allowsEditing = false
picker.sourceType = .PhotoLibrary
// picker.modalPresentationStyle = .Popover
presentViewController(picker,
animated: true,
completion: nil)
picker.popoverPresentationController?.sourceView = self.view
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
image = chosenImage
self.performSegueWithIdentifier("ShowEditView", sender: self)
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(false, completion: nil)
}
// MARK: Seque to EditViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowEditView" {
if let vc = segue.destinationViewController as? EditViewController {
vc.image = image
}
}
}
}
Swift 3.0 (only the extension code has syntax changes):
func openCameraApp() {
if UIImagePickerController.availableCaptureModes(for: .rear) != nil {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.camera
picker.cameraCaptureMode = .photo
picker.modalPresentationStyle = .fullScreen
present(picker,
animated: true,
completion: nil)
} else {
noCamera()
}
}
func noCamera(){
let alertVC = UIAlertController(
title: "No Camera",
message: "Sorry, this device has no camera",
preferredStyle: .alert)
let okAction = UIAlertAction(
title: "OK",
style:.default,
handler: nil)
alertVC.addAction(okAction)
present(
alertVC,
animated: true,
completion: nil)
}
// MARK: Photos Albums
func showImagePicker() {
picker.allowsEditing = false
picker.sourceType = .photoLibrary
// picker.modalPresentationStyle = .Popover
present(picker,
animated: true,
completion: nil)
picker.popoverPresentationController?.sourceView = self.view
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
image = chosenImage
self.performSegue(withIdentifier: "ShowEditView", sender: self)
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: false, completion: nil)
}
// MARK: Seque to EditViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowEditView" {
if let vc = segue.destination as? EditViewController {
vc.image = image
// vc.image = images[0]
}
}
}

Camera is not responding

Would please review my code, I do not have any errors, but when I open my view controller, the camera doesn't start there is only a black screen, even the buttons do not appear.
import UIKit
import AVFoundation
class CameraViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
let picker = UIImagePickerController()
#IBOutlet weak var myImageView: UIImageView!
#IBOutlet weak var cameraView: UIView!
#IBAction func photoLibrary(_ sender: UIBarButtonItem) {
picker.allowsEditing = false
picker.sourceType = .photoLibrary
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
picker.modalPresentationStyle = .popover
present(picker, animated: true, completion: nil)
picker.popoverPresentationController?.barButtonItem = sender
}
#IBAction func shootPhoto(_ sender: UIBarButtonItem) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.camera
picker.cameraCaptureMode = .photo
picker.modalPresentationStyle = .fullScreen
present(picker,animated: true,completion: nil)
} else {
noCamera()
}
}
func noCamera(){
let alertVC = UIAlertController(
title: "No Camera",
message: "Sorry, this device has no camera",
preferredStyle: .alert)
let okAction = UIAlertAction(
title: "OK",
style:.default,
handler: nil)
alertVC.addAction(okAction)
present(
alertVC,
animated: true,
completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
}
//MARK: - Delegates
private func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject])
{
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage //2
myImageView.contentMode = .scaleAspectFit //3
myImageView.image = chosenImage //4
dismiss(animated:true, completion: nil) //5
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
}
I only get completely black screen, even no hints from Swift. I do not know what to do now.
This happens when you have not set an initial viewcontroller. Please make sure the viewcontroller you want to load first is set as initial viewcontroller in your storyboard.

Swift - How can I get a list of all photos and videos on iPhone?

I would like to be able to view a list of both photos and videos stored on the user's iPhone so I can allow them to select the file for upload. So far, I have it working where photos show up in the list, but no videos are showing up. The code I'm using to display the photos library is the following:
#IBAction func btnAddPicOrVideo(sender: AnyObject) {
let pickerC = UIImagePickerController()
pickerC.delegate = self
self.presentViewController(pickerC, animated: true, completion: nil)
}
As I mentioned, I'm able to display a list of photos and select one of them just fine. The problem is that I'm unable to see or select any videos. Is there a way to specify for both pictures and videos to be displayed? Or, do I have to display pictures and videos separately?
I'm currently running my code on the simulator and I have a video file stored on it locally.
Thanks in advance.
I was able to get this resolved by specifying
import MobileCoreServices
and I changed the code I specified above as such:
#IBAction func btnAddPicOrVideo(sender: AnyObject) {
let pickerC = UIImagePickerController()
pickerC.mediaTypes = [kUTTypeImage as NSString, kUTTypeMovie as NSString]
pickerC.delegate = self
self.presentViewController(pickerC, animated: true, completion: nil)
}
class ScoutDetailPage: UIViewController,UIImagePickerControllerDelegate {
var picker:UIImagePickerController? = UIImagePickerController()
let imageView = UIImageView ()
{
override func viewDidLoad(){
// Do any additional setup after loading the view.
self.loadOrTakePhotos()
}
func loadOrTakePhotos()
{
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
{
picker!.sourceType = UIImagePickerControllerSourceType.Camera
picker?.delegate = self
self .presentViewController(picker!, animated: true, completion: nil)
}
}
else if (pickersegment.selectedSegmentIndex == 1)
{
picker!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
picker?.delegate = self
self.presentViewController(picker!, animated: true, completion: nil)
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
let pickedimage = info[UIImagePickerControllerOriginalImage] as! UIImage
imageView.image = pickedimage
if (imageView.image != nil)
{
print("image not empty")
// Do something here.
picker .dismissViewControllerAnimated(false, completion: nil)
}
else
{
print("IMAGE VIEW NIL")
}
}
func image(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo:UnsafePointer<Void>) {
if error != nil {
let alert = UIAlertController(title: "Save Failed",
message: "Failed to save image",
preferredStyle: UIAlertControllerStyle.Alert)
let cancelAction = UIAlertAction(title: "OK",
style: .Cancel, handler: nil)
alert.addAction(cancelAction)
self.presentViewController(alert, animated: true,
completion: nil)
}
}
}

Resources