I have an app that allows users to take selfies and upload it to Facebook, but the selfieTapped button I created is not working. It brings up a black screen. It does not let the user pick a photo from their library nor does it allow the user to take a picture.
import UIKit
import Social
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
#IBOutlet weak var myImageView: UIImageView!
#IBAction func selfieTapped(sender: AnyObject) {
//this method will be called when the user has taken a photo or has selected a photo from the photo library
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) {
//takes the image parameter and displays it inside myImageView
myImageView.image = image
//hides the imagePicker and animates the transition
self.dismissViewControllerAnimated(true, completion: nil)
}
//creates a new UIImagePickerController and sets it to the imagePicker variable
let imagePicker = UIImagePickerController()
//self the imagePicker's delegate property to the current view controller
imagePicker.delegate = self
//sets the imagePicker's sourceType property to .Camera
if UIImagePickerController.isSourceTypeAvailable(.Camera) {
//checking if a front camera is available
imagePicker.sourceType = .Camera
//if so, set it to the front camera
if (UIImagePickerController.isCameraDeviceAvailable(.Front)) {
//setting it to the front camera
imagePicker.cameraDevice = .Front
} else {
//setting it to the rear camera if the front is not available
imagePicker.cameraDevice = .Rear
}
} else {
//if the camera is not available, the photo library will be shown
imagePicker.sourceType = .PhotoLibrary
}
//presents the imagePicker modally, sliding it up from the bottom of the screen and it animates the transition
self.presentViewController(imagePicker, animated: true, completion: nil)
}
#IBAction func shareTapped(sender: AnyObject) {
//sets the serviceType property to Facebook
let facebookSocial = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
//myImageView image is added to the Facebook post
facebookSocial.addImage(myImageView.image)
//it is displayed and uses animation
self.presentViewController(facebookSocial, animated: true, completion: nil)
}
}
Please check if you have closed Camera & Photos permission for your app in Setting.
This may not be the cause of the trouble, but it certainly will be trouble later: you've put one function inside of another:
#IBAction func selfieTapped(sender: AnyObject) {
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) {
Don't do that. They both need to be at the same level, as methods of your class. Otherwise, didFinishPickingImage can never be called.
Related
I'm trying to use a UIImagePickerController to show a image picked from the Photo Library, but when I select the image, nothing happens.
All I'm doing is from Apple's Swift tutorial, so the code shouldn't be wrong, I guess. It doesn't work neither in simulator nor on a real device. I've tried all suggestions I found while googling. My code:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//MARK: Properties
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var mealNameLabel: UILabel!
#IBOutlet weak var photoImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
nameTextField.delegate = self
}
//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, completion: nil)
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
// Dismiss the picker if the user canceled.
dismiss(animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// The info dictionary may contain multiple representations of the image. You want to use the original.
guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image.
photoImageView.image = selectedImage
// Dismiss the picker.
dismiss(animated: true, completion: nil)
}
}
#IBAction func setDefaultLabelText(sender: UIButton) {
mealNameLabel.text = "Default Text"
}
//MARK: UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
mealNameLabel.text = textField.text
}
}
I can provide more information if necessary. Thanks in advance.
Your delegate method is in the button action scope.
You have to write UIImagePickerControllerDelegate method out of the selectImageFromPhotoLibrary action scope and write with the proper signature.
Just like that:
#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, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
// Dismiss the picker if the user canceled.
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// The info dictionary may contain multiple representations of the image. You want to use the original.
guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image.
photoImageView.image = selectedImage
// Dismiss the picker.
dismiss(animated: true, completion: nil)
}
So right now I am trying to get the collection view Cells to use the photo library to update photos. Here is my code:
import UIKit
class viewCellVC: UICollectionViewCell, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var bookImage: UIImageView!
#IBAction func addImage(_ sender: Any) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePicker.allowsEditing = false
self.window?.rootViewController?.present(imagePicker, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
bookImage.image = image
picker.dismiss(animated: true, completion: nil)
}
}
However, when I attempt to run the code and update the pictures, the simulator fails to open the photo library and I instead get the following error message(doesn't end the app, just fails to run the photo library):
2017-08-07 21:35:31.709183-0500 ChuBookElf[2817:66569] Warning: Attempt to present <UIImagePickerController: 0x7f907e0bf800> on <ChuBookElf.ViewController: 0x7f907de072c0> whose view is not in the window hierarchy!
Can somebody tell my what I am doing wrong? I've been on this for hours now.
For Reference, here is what the collection view cell looks like
For starters, you are creating the imagePicker in a UICollectionViewCell.
You should create the imagePicker in the ViewController that contains the said UICollectionView along with the delegate methods. Then, in didFinishPickingMediaWithInfo, set the selected image to the appropriate collectionViewCell and reload your collectionView
Have such part of my storyboard:
So I want present from UserProfileController: UIViewController "Мой профиль", which is modal, (on the top on image) UIImageViewController.
My code:
extension UserProfileController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBAction func imagePressed(_ sender: Any) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
self.present(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else {
return
}
picker.dismiss(animated: true, completion: nil)
userProfileImageView.image = image
}
}
Well, imagePickerController presented, but after I choose image I have dismissed both controllers (imagePickerController and parent - UserProfileControler).
What am I doing wrong? Thanks
P.S. May be problem is I'm showing "SideMenuNavigationController" as modal? (so advised in SideMenu framework documentation)
Try to create you UIImagePickerController reference in your class (as a variable)
// to choose an image from the Camera Roll
fileprivate lazy var imagePicker: UIImagePickerController = {
let picker: UIImagePickerController = UIImagePickerController()
picker.allowsEditing = false
picker.sourceType = .savedPhotosAlbum
picker.delegate = self
return picker
}()
I am trying to make an image uploader on my ios app.
EDIT 7
This question is now more clearly asked here: Present Modal for Image Select Erases UI
END OF EDIT 7
The first thing I am trying to do is enable the user to select an image that they want for upload.
EDIT 6
I have simplified all the code to simply one button press. The Modal presentation deletes the previous page's UI. How I prevent this.
import UIKit
class AddImageToStandViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func loadImageButtonTapped(sender: UIButton) {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
I have found that the selection works just fine and does not destroy the UI if I push/segue from a different to this controller.
END OF EDIT 6
Below this is the other methods that I have tried before this
So far, this code enables a user to press a button and choose a photo from their photos. But, after they click the photo it just returns them to an empty View except the navbar at the bottom.
It seems my user is being returned, not to the view that they came from, but to a separate empty view. How do I return the user to the view that they came from?
import UIKit
class CreateStandViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var image: UIImageView!
...
#IBAction func selectPicture(sender: AnyObject) {
let ImagePicker = UIImagePickerController()
ImagePicker.delegate = self
ImagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(ImagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.dismissViewControllerAnimated(true, completion: nil)
}
...
let me know if there is any more information that I should give.
EDIT 1
this code has the same effect
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
picker.dismissViewControllerAnimated(true, completion: nil)
}
I have tried adding this line below but I get an error stating that CreateStandViewController.Type cannot be converted to the expected UIViewController.
self.presentViewController(CreateStandViewController, animated: true, completion: nil)
EDIT 2
This code below doesnt error but also changes nothing
let createStandController = CreateStandViewController()
self.presentViewController(createStandController, animated: true, completion: nil)
EDIT 3
I have literally copied all the code from here: http://www.codingexplorer.com/choosing-images-with-uiimagepickercontroller-in-swift/ and now have:
import UIKit
class CreateStandViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var imageView: UIImageView!
let imagePicker = UIImagePickerController()
#IBAction func loadImageButtonTapped(sender: UIButton) {
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
presentViewController(imagePicker, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
// MARK: - UIImagePickerControllerDelegate Methods
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
}
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
}
This has the same issue as before. When the image is selected I am sent back to a view that is white with the navbar at the bottom.
EDIT 4
I have run the same code in its own separate project as a stand alone view controller and it works. There is some code that I have in the background of my app that is killing the functionality of the code (maybe). I am guessing it may have something to do with the navbar?
EDIT 5
I removed the tab bar at the bottom by seguing to the image selecting view via a present Modally segue, but it had no effect.
Just replace your
self.dismissViewControllerAnimated(true, completion: nil)
with
picker.dismissViewControllerAnimated(true, completion: nil)
I think you will get the point after that
I am able to start the UIImagePickerController to make a picture:
func selectCamera(){
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.Camera;
imagePicker.allowsEditing = true
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
and with this function to choose from the saved pictures:
func selectPicture() {
let picker = UIImagePickerController()
picker.allowsEditing = true
picker.delegate = self
presentViewController(picker, animated: true, completion: nil)
}
I can either choose a image from my image gallery on the phone or take a picture.
But i want to choose one of the saved image gallery pics inside the camera view, how it is in the standard camera application. Is this possible?
If you want to have Gallery Pics inside camera view, you got to create a custom cameraOverlay view, which has a button to then open the saved pictures.
To make it faster, you can use a library like --> https://github.com/GabrielAlva/Cool-iOS-Camera
Or
You can also have a action sheet, asking user to select which option he wants.
Check this -> How to allow the user to pick a photo from his camera roll or photo library?
& this --> https://github.com/chroman/CRMediaPickerController
I am using this solution, without additional libraries.
First of all don't forget to delegate, UIImagePickerControllerDelegate, and navigation delegate. Those thigns needed only for imagePickerController.
Update, check function saveImageViewToAlbum, be sure that your imageView containt image, otherwise you probably will catch exception. Adds a photo to the saved photos album. The optional completionSelector should have the form:
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
Just created this project, and everything works on swift, iOS 9.3
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var choosenImageView: UIImageView!
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.
}
#IBAction func openAlbum(sender: UIButton) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self .presentViewController(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
choosenImageView.image = image
self .dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func saveImageViewToAlbum(sender: UIButton) {
UIImageWriteToSavedPhotosAlbum(choosenImageView.image!, nil, nil, nil)
}
}