Within my app I can take a picture
I have a button to access the camera (with all the permission and all)
it works, I can take a picture or close it if i wanted to
but after doing either of the activity
the camera button wont open the camera again
I have to exit the view controller and go back again for it to work
#IBAction func cameraButton(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.camera) && !pickedImage {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
pickedImage = true
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
imageView.image = image
self.dismiss(animated: true, completion: nil)
}
After taking a picture there is a UIImageView for it to display taken picture.
I need to two things
1. In the camera access i can also select pictures from the gallery and make it display on the UIImageView
2. To have the camera button reopen the camera after using it
To select pictures from gallery, you will have to set sourceType as .photoLibrary .
I think your pickedImage variable is never set to false, hence the second time, it doesn't get inside that if condition.
Related
I am developing in Swift with iPhone camera.
I using the following code to check the camera:
if UIImagePickerController.isSourceTypeAvailable(.Camera) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = UIImagePickerControllerSourceType.Camera
picker.allowsEditing = true
self.presentViewController(picker, animated: true)
} else {
print("can't find camera")
}
}
And I use the following code to open the camera.
presentViewController(imagePicker, animated: true, completion: nil)
I have reference the following link and call takePicture() , but it seems did not working.
But I always need to manually take the picture by tapping the shutter button. Is programmatically taking the picture possible in Swift?
Thanks in advance.
1) Check if you have these delegates in your view controller class:
UIImagePickerControllerDelegate, UINavigationControllerDelegate
2) Check if your plist have the permissions with YES
Privacy - Photo Library Usage Description
Privacy - Camera Usage Description
If you want, I use this code (swift 3):
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
self.present(imagePicker, animated: true, completion: nil)
For camera, just change "photoLibrary"
imagePicker.sourceType = .camera
3) In order to get the picture, you must implement the delegate didFinishPickingMediaWithInfo:
extension YourViewController:
UIImagePickerControllerDelegate,
UINavigationControllerDelegate
{
func imagePickerController(
_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any])
{
imagePicker.dismiss(animated: true, completion: nil)
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
print("picture taken: \(image)")
}
}
var imagePicker:UIImagePickerController = UIImagePickerController()
//Set delegate to imagePicker
imagePicker.delegate = self
//Allow user crop or not after take picture
imagePicker.allowsEditing = false
//set what you need to use "camera or photo library"
imagePicker.sourceType = .camera
//Switch flash camera
imagePicker.cameraFlashMode = .off
//Set camera Capture Mode photo or Video
imagePicker.cameraCaptureMode = .photo
//set camera front or rear
imagePicker.cameraDevice = .rear
//Present camera viewcontroller
self.present(imagePicker, animated: true, completion: nil)
and don't forget implement two protocol: UIImagePickerControllerDelegate,UINavigationControllerDelegate
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let imagePicked = info[UIImagePickerControllerOriginalImage] as? UIImage {
UIImageWriteToSavedPhotosAlbum(imagePicked, nil, nil, nil)
dismiss(animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
Because you want to take picture fully automatically, you don't need UIImagePickerController at all. Instead use AVFoundation directly.
This article will be very helpful: Camera Capture on iOS.
I'm working on an onboarding flow for my app. I'm wanting to allow users to pick an avatar, display that avatar in an image view, and then select a background photo and display that in another image view. Currently, I have everything coded up, but for some reason when I present the picker controller, it defaults to controller for the avatar. I want the avatar button to only control the avatar button background image and the background button to only control the header image background image. Here's my code:
#IBAction func getBackground(sender: AnyObject) {
let backgroundPickerController = UIImagePickerController()
backgroundPickerController.delegate = self
backgroundPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
backgroundPickerController.allowsEditing = true
self.presentViewController(backgroundPickerController, animated: true, completion: nil)
}
#IBAction func selectAvatar(sender: AnyObject) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
imagePickerController.allowsEditing = true
self.presentViewController(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
// set image for button
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.addAvatar.setImage(image, forState: .Normal)
// Dismiss controller
self.dismissViewControllerAnimated(false, completion: nil)
}
func backgroundPickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
// set image for button
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.headerImage.image = image
self.dismissViewControllerAnimated(false, completion: nil)
}
The delegate function imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) also returns the UIImagePickerController that finished picking an image.
So you can use an if statement to check if the picker that finished is pickerOne or pickerTwo. Then you implement different behaviour according to the result of that.
Maybe set the pickers to nil after they have finished to clean up some memory.
class multiPickerVC : UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var pickerOne : UIImagePickerController?
var pickerTwo : UIImagePickerController?
override func viewDidLoad() {
//
}
#IBAction func getBackground(sender: AnyObject) {
pickerTwo = UIImagePickerController()
pickerTwo!.delegate = self
pickerTwo!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
pickerTwo!.allowsEditing = true
self.presentViewController(pickerTwo!, animated: true, completion: nil)
}
#IBAction func selectAvatar(sender: AnyObject) {
pickerOne = UIImagePickerController()
pickerOne!.delegate = self
pickerOne!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
pickerOne!.allowsEditing = true
self.presentViewController(pickerOne!, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
if picker == pickerOne {
// set image for button
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.addAvatar.setImage(image, forState: .Normal)
} else if picker == pickerTwo {
// set image for button
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.headerImage.image = image
}
self.dismissViewControllerAnimated(true, completion: nil)
}
}
I have an action sheet that has two options: one where you can choose an image from your library and one where you can take a photo from the camera. The photo library functions properly, but I can't seem to get the camera to work.
Here is my code:
let takePhoto = UIAlertAction(title: "Take photo", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
// present camera taker
var cameraPicker = UIImagePickerController()
cameraPicker.delegate = self
cameraPicker.sourceType = .Camera
self.presentViewController(cameraPicker, animated: true, completion: nil)
})
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
var selectedAvatar = UIImagePickerControllerOriginalImage
self.dismissViewControllerAnimated(false, completion: nil)
}
I can't seem to find the problem, can anybody help me out? The program crashes when I try to run it and click on Take Photo.
You are most likely running in the simulator. The simulator dont have a camera so to not make the app crash when pressing the button you have to check if cemera is available.
if UIImagePickerController.isSourceTypeAvailable(.Camera) {
...
}
else {
print("Sorry cant take picture")
}
Follow the below code
func takePhoto()
{
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
{
picker!.sourceType = UIImagePickerControllerSourceType.Camera
self .presentViewController(picker!, animated: true, completion: nil)
}
else
{
let alertWarning = UIAlertView(title:"Warning", message: "You don't have camera", delegate:nil, cancelButtonTitle:"OK", otherButtonTitles:"")
alertWarning.show()
}
}
func openGallary()
{
picker!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(picker!, animated: true, completion: nil)
}
//PickerView Delegate Methods
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])
{
picker .dismissViewControllerAnimated(true, completion: nil)
imageView.image=info[UIImagePickerControllerOriginalImage] as? UIImage
}
func imagePickerControllerDidCancel(picker: UIImagePickerController)
{
println("picker cancel.")
}
There is another reason why the camera can crash when used in a real device as Kirit Modi said in the following tread:
iOS 10 - App crashes To access photo library or device camera via UIImagePickerController
In iOS 10. You have to set privacy Setting for Camera & Photo Library. Camera & Photo Privacy Setting at info.Plist
This solved my crashing issue!
So far I have the camera working fine, it opens up in the regular format. But I want the only option to be square format.
Here is my code so far.
#IBAction func takePhoto(sender: AnyObject) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .Camera
presentViewController(picker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
dismissViewControllerAnimated(true, completion: nil)
}
I don't think you can open camera in square format using UIImagePickerController. What you can do is set UIImagePickerController allowEditing to YES and from the result dict use the key UIImagePickerControllerEditedImage then you will have the squared image so you code becomes .
#IBAction func takePhoto(sender: AnyObject) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .Camera
picker.allowsEditing = true
presentViewController(picker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
imageView.image = info[UIImagePickerControllerEditedImage] as? UIImage
dismissViewControllerAnimated(true, completion: nil)
}
Another way around is mentioned in this answer .
You can use the logic from answer to write the code in swift.
But if you want to look in details and try out doing some more have a look into
AVFoundation,
AVCaptureConnection,
AVCaptureDevice
AVCaptureDeviceInput
AVCaptureSession
AVCaptureStillImageOutput
AVCaptureVideoDataOutput
AVCaptureVideoPreviewLayer
CoreImage
Also look at apple sample.
I'm making an app that the user can add his image to a table view list. When he gets to the view, an alert, action sheet styled, pops up asking him if he wants to take the picture, choose from the library or cancel.
I'm having trouble with the second. I'm able to open the library with buttons using the following code:
#IBOutlet weak var imageView: UIImageView!
#IBAction func loadPhoto(sender: AnyObject) {
let pickerC = UIImagePickerController()
pickerC.delegate = self
self.presentViewController(pickerC, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController!, didFinishPickingMediaWithInfo info: NSDictionary!) {
self.dismissViewControllerAnimated(true, completion: nil);
let gotImage = info[UIImagePickerControllerOriginalImage] as UIImage
imageView.image = gotImage
}
But when I try using this code with an UIAlertAction it doesn't work. Can someone help me, please?
Thanks
class ViewController: UIViewController, UIImagePickerControllerDelegate
Then write following code where you want to open UIImagePickerController.
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary
){
println("Button capture")
var imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary;
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
Then implement following delegate method.
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!){
self.dismissViewControllerAnimated(true, completion: { () -> Void in
})
imageView.image = image
}