iOS 8/Xcode 6 - Add action to AlertSheet button [duplicate] - ios

This question already has an answer here:
Thread 1: signal SIGABRT error when using IBActions?
(1 answer)
Closed 7 years ago.
I am writing a basic photo app that allows a user to push a "+" button in a navigation controller and then an ActionSheet pops up from the bottom giving the user options, here is a picture:
I have the code to get this app working using normal buttons, but when I added it to my code for this app it crashes. Here is the code:
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate
{
#IBOutlet weak var imageView: UIImageView!
#IBAction func addPhoto(sender: UIBarButtonItem)
{
let photoOption = UIAlertController(title: nil, message: "Select an Input Type", preferredStyle: .ActionSheet)
let photoLibraryAction = UIAlertAction(title: "Photo Library", style: .Default) { (alert: UIAlertAction!) -> Void in
println("Photo Library Selected") // Used for debugging
// This code worked in my previous app
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .PhotoLibrary
self.presentViewController(picker, animated: true, completion: nil)
}
let cameraAction = UIAlertAction(title: "Camera", style: .Default) { (alert: UIAlertAction!) -> Void in
println("Camera Selected") // Used for debugging
// This code worked in my previous app
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .Camera
self.presentViewController(picker, animated: true, completion: nil)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
photoOption.addAction(photoLibraryAction)
photoOption.addAction(cameraAction)
photoOption.addAction(cancelAction)
self.presentViewController(photoOption, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController!, didFinishPickingMediaWithInfo info: [NSObject: AnyObject]!)
{
imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
dismissViewControllerAnimated(true, completion: nil)
}
}
and the strange thing is after I ran this and the app crashed, I reverted back to when the code was working and the app still crashed.

The problem is that you are running this code in the simulator. But the simulator has no camera. It's just a simulator!
Hence, trying to summon an image picker controller with a .Camera source type causes an exception - with a helpful error message in the console that you could have read, thus avoiding wasting bandwidth with this question...

Related

Error while opening Popover Option to choose either Camera or photo Library on iPad in Xcode

I am able to open a Photo Library on an iPhone using the following code:-
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBAction func TapOnImageView(sender: UITapGestureRecognizer) {
//call Alert function
self.showAlert()
}
//Show alert to selected the media source type.
private func showAlert() {
let alert = UIAlertController(title: "Image Selection", message: "From where you want to pick this image?", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action: UIAlertAction) in
self.getImage(fromSourceType: .camera)
}))
alert.addAction(UIAlertAction(title: "Photo Album", style: .default, handler: {(action: UIAlertAction) in
self.getImage(fromSourceType: .photoLibrary)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
}
//get image from source type
private func getImage(fromSourceType sourceType: UIImagePickerController.SourceType) {
//Check is source type available
if UIImagePickerController.isSourceTypeAvailable(sourceType) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = sourceType
self.present(imagePickerController, animated: true, completion: nil)
}
}
//MARK:- UIImagePickerViewDelegate.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
self.dismiss(animated: true) { [weak self] in
guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return }
//Setting image to your image view
self?.imageView.image = image
self?.imageView.contentMode = .scaleToFill
self?.image = self?.imageView.image
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
But, when I am running my app on iPad, I am getting the following error:-
Thread 1: Exception: "Your application has presented a UIAlertController (<UIAlertController: 0x7ffd07875e00>) of style UIAlertControllerStyleActionSheet from App Name.ViewController (<App_Name.ViewController: 0x7ffd07635620>). The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation."
Could anyone please let me know, what can I do to open camera and Photo Library on iPad in Xcode? Thanks for the help!
Updated:
Solution:
var alertStyle = UIAlertController.Style.actionSheet
if (UIDevice.current.userInterfaceIdiom == .pad) {
alertStyle = UIAlertController.Style.alert
}
let alert = UIAlertController(title: "Image Selection", message: "From where you want to pick this image?", preferredStyle: alertStyle)
You are trying to present an UIAlertController on iPad which requires to set modalStyle to UIModalPresentationPopover and its sourceView and sourceRect. Please see this answer for more details.

When i tap on image button for UIImagePicker galary to pick image in iPad then app is crashing why?

I am using UIImagePicker for picking images, it forks fine for iPhone gallery to pick images. but when i test app in iPad in xcode here when i tap on image button then app is crashing, i dont know why.
here is the code:
#IBAction func addProfileBtnAction(_ sender: Any) {
let actionSheetController: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
//Create and add the Cancel action
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in
//Just dismiss the action sheet
}
actionSheetController.addAction(cancelAction)
//Create and add first option action
let takePictureAction: UIAlertAction = UIAlertAction(title: "TakePhoto", style: .default) { action -> Void in
//Code for launching the camera goes here
self.openCameraPicker()
}
actionSheetController.addAction(takePictureAction)
//Create and add a second option action
let choosePictureAction: UIAlertAction = UIAlertAction(title: "ChooseFromLibrary", style: .default) { action -> Void in
//Code for picking from Gallery goes herece
self.openPhotoGallery()
}
actionSheetController.addAction(choosePictureAction)
//Present the AlertController
self.present(actionSheetController, animated: true, completion: nil)
}
func openCameraPicker() {
picker.sourceType = UIImagePickerController.SourceType.camera
picker.cameraCaptureMode = .photo
picker.modalPresentationStyle = .fullScreen
present(picker,animated: true,completion: nil)
}
func openPhotoGallery() {
picker.sourceType = .photoLibrary
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
present(picker, animated: true, completion: nil)
}
// MARK: - UIImagePickerControllerDelegate Methods
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
//pickedImage = image
imgPick.image = image
}
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
i have checked the crash point by giving breakpoint, when it comes to openPhotoGallery() then its crashing.
UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in may also be helpful.
please help me with the code. to pic images from iPad gallery as well.
For iPad add your code :
(under the let actionSheetController: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) line)
actionSheetController.popoverPresentationController?.sourceView = self.yourView
Hope it helps...

UIImagePickerController working without NS Photo Library and Camera descriptions

I am working with UIImagePickerController because I am creating an application that allows for the posting of images through both the photo library and camera. I created a basic demo that consists of a UIImageView, UIButton with some code to set up the UIImagePickerController. In addition, I have also set up (NSPhotoLibraryUsageDescription and NSCameraUsageDescription) in the plist section of Xcode. The image picking function works beautifully yet when I run the simulator I am not being queried on whether or not I should let the app allow access to either my camera or photo library. I then tried taking the plist statements off and running again. Without these, the app should crash however it does not. My question is what am I doing wrong here for the picker to work without the plist and why does the app not ask for permissions with the NS usage statements?
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
#IBAction func importImage(_ sender: UIButton) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let actionSheet = UIAlertController(title: "Add Your Profile Picture", message: "Choose An Option", preferredStyle: . actionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (action:UIAlertAction) in
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
}
else {
print("Camera not Available")
}
}))
actionSheet.addAction(UIAlertAction(title: "Camera Roll", style: .default, handler:{ (action:UIAlertAction) in imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil
))
self.present(actionSheet, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
imageView.image = image
picker.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Storyboard View
plist image
why does the app not ask for permissions with the NS usage statements
This is due to a change in iOS 11. You no longer need user authorization merely to receive a UIImage through the UIImagePickerController.
But if you want deeper information, i.e. access to the image as a PHAsset and its metadata, you do need user authorization.
And of course if you want this app to run on iOS 10 and before, you'll still need user authorization.

I want to let users choose either taking a photo using camera or picking a photo from library(ios-swift, apple example- foodtracker)

I'm playing with ios swift foodtracker example.
The default final example only let users choose a photo from a library.
But I want them to take a photo using camera.
So I tried the below code, but it didn't change the functionality. It still did went to the photo library without asking the user's option preference (camera/photolibrary).
I am getting the following error message:
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior ()
And this is the code I used:
#IBAction func selectImageFromPhotoLibrary(sender: AnyObject) {
// Hide the keyboard.
nameTextField.resignFirstResponder()
// UIImagePickerController is a view controller that lets a user pick media from their photo library.
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .Default, handler: {
action in
imagePickerController.sourceType = .Camera
self.presentViewController(imagePickerController, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Photo Library", style: .Default, handler: {
action in
imagePickerController.sourceType = .PhotoLibrary
self.presentViewController(imagePickerController, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(imagePickerController, animated: true, completion: nil)
}
Make sure you are using Navigation Controller, if not just embed it by going to your storyBoard --> Select your initial ViewController then Editor ->Embeded In -> Navigation Controller
To use imagePicker , use This : -
class ViewController : UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
.....
.....
.....
var imagePicker : UIImagePickerController!
//Defined it globally in the class
..
..
override func viewDidLoad() {
super.viewDidLoad()
imagePicker = UIImagePickerController()
self.imagePicker.delegate = self
//Initialise it in viewDidLoad
...
}
//In your 'selectImageFromPhotoLibrary' function : -
#IBAction func selectImageFromPhotoLibrary(sender: AnyObject) {
let alertController : UIAlertController = UIAlertController(title: "Camera / Photo Album ", message: "", preferredStyle: UIAlertControllerStyle.ActionSheet)
let cameraAction : UIAlertAction = UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default) { (UIAlertAction) -> Void in
if (UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)) {
self.imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
} else {
print("Camera not available")
}
self.present()
}
alertController.addAction(cameraAction)
let photoLibraryAction : UIAlertAction = UIAlertAction(title: "Photo Library", style: UIAlertActionStyle.Default) { (UIAlertAction) -> Void in
if (UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary)) {
self.imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
} else {
print("Photo Library not available")
}
self.present()
}
alertController.addAction(photoLibraryAction)
alertController.popoverPresentationController?.sourceView = view
alertController.popoverPresentationController?.sourceRect = view.frame
presentViewController(alertController, animated: true, completion: nil)
}
...
...
// After you are done picking up image , this function will be automatically be called.
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
print("info reached")
imagePicker.dismissViewControllerAnimated(true, completion: nil)
//Now do whatever you want to do with your picked image.
}
//For presenting the imagePicker Controller.
func present(){
self.presentViewController(self.imagePicker, animated: true, completion: nil)
}
}
If you get stuck on how to extract image just check this link out : Swift - UIImagePickerController - how to use it?
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImagePickerController_Class/

Swift 2: Image picker crashes after at didFinishPickingMediaWithInfo

I am creating an app that utilises this image picker code retrieved from: https://github.com/projectwakii/UIImagePickerController-in-Swift
Shown below:
#IBAction func imageButtonDidPress(sender: AnyObject) {
print("pressed")
//show the action sheet (i.e. the little pop-up box from the bottom that allows you to choose whether you want to pick a photo from the photo library or from your camera
let optionMenu = UIAlertController(title: nil, message: "Where would you like the image from?", preferredStyle: UIAlertControllerStyle.ActionSheet)
let photoLibraryOption = UIAlertAction(title: "Photo Library", style: UIAlertActionStyle.Default, handler: { (alert: UIAlertAction!) -> Void in
print("from library")
//shows the photo library
self.imagePicker.allowsEditing = true
self.imagePicker.sourceType = .PhotoLibrary
self.imagePicker.modalPresentationStyle = .Popover
self.presentViewController(self.imagePicker, animated: true, completion: nil)
})
let cameraOption = UIAlertAction(title: "Take a photo", style: UIAlertActionStyle.Default, handler: { (alert: UIAlertAction!) -> Void in
print("take a photo")
//shows the camera
self.imagePicker.allowsEditing = true
self.imagePicker.sourceType = .Camera
self.imagePicker.modalPresentationStyle = .Popover
self.presentViewController(self.imagePicker, animated: true, completion: nil)
})
let cancelOption = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: {
(alert: UIAlertAction!) -> Void in
print("Cancel")
self.dismissViewControllerAnimated(true, completion: nil)
})
//Adding the actions to the action sheet. Camera will only show up as an option if the camera is available in the first place.
optionMenu.addAction(photoLibraryOption)
optionMenu.addAction(cancelOption)
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) == true {
optionMenu.addAction(cameraOption)} else {
print ("I don't have a camera.")
}
self.presentViewController(optionMenu, animated: true, completion: nil)
/*
just adding extra text for fun
*/
}
// MARK: - Image Picker Delegates
//The UIImagePickerController is a view controller that gets presented modally. When we select or cancel the picker, it runs the delegate, where we handle the case and dismiss the modal.
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
print("finished picking image")
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
//handle media here i.e. do stuff with photo
print("imagePickerController called")
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
imageButtonImage.image = chosenImage
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
//what happens when you cancel
//which, in our case, is just to get rid of the photo picker which pops up
dismissViewControllerAnimated(true, completion: nil)
}
The issue is that most of the times that I select an image the app crashes.I think it is partially due to some sort of low memory warning, although I am not sure. It is after I click the "use photo" button as shown below
Also, does anybody have any idea how I can remove the square thing whenever I take the photo as visible above
Thanks in advance!
Try using:
self.imagePicker.allowsEditing = false

Resources