I'm desperately trying to add video picking option to my app. The app can take a picture and select pictures but it cannot select video file. I want the users to be able to select video from the photo library just as easily as they can select a photo. But most people I have asked seem to think it is not possible. But of course, it is not. I have used many app with this feature. Or this is not something I can do with Xcode?
}
let actionsheet = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
actionsheet.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { (alert: UIAlertAction) in
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
let mypickerController = UIImagePickerController()
mypickerController.delegate = self
mypickerController.sourceType = .photoLibrary
self.present(mypickerController, animated: true, completion: nil)
}
}))
actionsheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (alert: UIAlertAction) in
if UIImagePickerController.isSourceTypeAvailable(.camera){
let myPickerController = UIImagePickerController()
myPickerController.delegate = self
myPickerController.sourceType = .camera
self.present(myPickerController, animated: true, completion: nil)
}
}))
actionsheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionsheet, animated: true, completion: nil)
}
#IBAction func onSaveButton(_ sender: Any) {
print("screenshot pressed")
//let appDelegate: AppDelegate? = UIApplication.shared.delegate as? AppDelegate
//appDelegate?.myInterstitial = appDelegate?.createAndLoadInterstitial()
if firstImage.image == nil{
GlobalFunction.sharedManager.setWhiteBackground(selectView: firstImage)
}
if secondImage.image == nil{
GlobalFunction.sharedManager.setWhiteBackground(selectView: secondImage)
}
if thirdImage.image == nil{
GlobalFunction.sharedManager.setWhiteBackground(selectView: thirdImage)
}
let image = GlobalFunction.sharedManager.takeScreenshot(theView: backView)//takeScreenshot(theView: backView)
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(image:didFinishSavingWithError:contextInfo:)), nil)
}
#IBAction func onCancelButton(_ sender: Any) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "mainVC") as! ViewController
self.present(vc, animated: true, completion: nil)
}
#IBAction func onAddButton(_ sender: Any) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "mainVC") as! ViewController
self.present(vc, animated: true, completion: nil)
}
#objc func image(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo: UnsafeRawPointer) {
DispatchQueue.main.async{
self.showAlertView(message: "Your story has been saved to your Camera Roll", completionHandler: { (a) in
let appDelegate: AppDelegate? = UIApplication.shared.delegate as? AppDelegate
appDelegate?.myInterstitial = appDelegate?.createAndLoadInterstitial()
})
//UIAlertView(title: "Success", message: "Your story has been saved to your Camera Roll", delegate: nil, cancelButtonTitle: "Close").show()
}
}
func takeScreenshot(theView: UIView) -> UIImage {
UIGraphicsBeginImageContextWithOptions(theView.bounds.size, true, 0.0)
theView.drawHierarchy(in: theView.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
func circleCropDidCancel() {
dismiss(animated: false, completion: nil)
}
func circleCropDidCropImage(_ image: UIImage) {
dismiss(animated: false, completion: nil)
if selected == 1{
firstImage.image = image
}else if selected == 2{
secondImage.image = image
}else if selected == 3{
thirdImage.image = image
}
}
}
UIImagePickerController has a mediaTypes property. It determines what kind of media the picker can pick. You are not setting mypickerController.mediaTypes to include videos.
Related
I want to pick two different images on two imageView's on one ViewController, display them, and after pushing the button save picked images to firebase database and storage to its particular user. My code only able to upload one picked image, not two different, I understand that the problem with UIImagePickerController part, but how can I resolve it. Full code of viewController is below. Please help!!
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(SettingProfileViewController.handleSelectProfileImageView(sender:)))
profilePhoto.addGestureRecognizer(tapGesture)
profilePhoto.isUserInteractionEnabled = true
let wallTapGesture = UITapGestureRecognizer(target: self, action: #selector(SettingProfileViewController.handleSelectWallpaperImageView(sender:)))
wallpaperPhoto.addGestureRecognizer(wallTapGesture)
wallpaperPhoto.isUserInteractionEnabled = true
profilePhoto.layer.cornerRadius = 60
profilePhoto.clipsToBounds = true
}
weak var activeImageView:UIImageView? = nil
#objc func handleSelectWallpaperImageView(sender: UIGestureRecognizer){
guard let sendingImageView = sender.view as? UIImageView else {
print("Ooops, received this gesture not from an ImageView")
return
}
activeImageView = sendingImageView
let actionSheet = UIAlertController(title: "New Photo", message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Камера", style: .default, handler: { action in
self.showCamera()
}))
actionSheet.addAction(UIAlertAction(title: "Альбом ", style: .default, handler: {action in
self.showAlbum()
}))
actionSheet.addAction(UIAlertAction(title: "Отмена", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
#objc func handleSelectProfileImageView(sender: UIGestureRecognizer){
guard let sendingImageView = sender.view as? UIImageView else {
print("Ooops, received this gesture not from an ImageView")
return
}
activeImageView = sendingImageView
let actionSheet = UIAlertController(title: "New Photo", message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Камера", style: .default, handler: { action in
self.showCamera()
}))
actionSheet.addAction(UIAlertAction(title: "Альбом ", style: .default, handler: {action in
self.showAlbum()
}))
actionSheet.addAction(UIAlertAction(title: "Отмена", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
func showCamera() {
let cameraPicker = UIImagePickerController()
cameraPicker.delegate = self
cameraPicker.sourceType = .camera
present(cameraPicker, animated: true, completion: nil)
}
func showAlbum(){
let cameraPicker = UIImagePickerController()
cameraPicker.delegate = self
cameraPicker.sourceType = .photoLibrary
present(cameraPicker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
dismiss(animated: true, completion: nil)
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage{
// selectedImage = image
activeImageView?.image = image
// currentImage = image
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
///для того чтобы загруженные фото, отображались на ProfileViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "profileVC" {
let destination = segue.destination as! ProfileViewController
destination.wImage = activeImageView?.image
}
}
#IBAction func saveTapped(_ sender: Any) {
let db = Firestore.firestore()
let did = Auth.auth().currentUser!.uid
let storageRef = Storage.storage().reference(forURL: "gs://crut-6c67c.appspot.com").child("profile_Image").child(did)
if let pImage = self.activeImageView?.image, let imageData = pImage.jpegData(compressionQuality: 0.1) {
storageRef.putData(imageData, metadata: nil, completion: {(metadata, Error) in
if Error != nil, metadata != nil {
return
}
storageRef.downloadURL { (url: URL?,error: Error?) in
if let profileImageUrl = url?.absoluteString{
db.collection("suppliers").document("ip").collection("ipinfo").document(did).setData(["Profile Image":profileImageUrl], merge: true)
}
}
})
}
let storyBoard: UIStoryboard = UIStoryboard(name: "Profile", bundle: nil)
let profileViewController = storyBoard.instantiateViewController(identifier:profile.Storyboard.profileViewController) as? ProfileViewController
self.view.window?.rootViewController = profileViewController
self.view.window?.makeKeyAndVisible()
}
}
You can make an instance variable in your viewController i.e.
private var isProfilePhotoSelecting = true
When user tap on profileImageView in handleSelectProfileImageView method set isProfilePhotoSelecting to true i.e.
#objc func handleSelectProfileImageView(sender: UIGestureRecognizer){
guard let sendingImageView = sender.view as? UIImageView else {
print("Ooops, received this gesture not from an ImageView")
return
}
// Updated the image under consideration
isProfilePhotoSelecting = true
let actionSheet = UIAlertController(title: "New Photo", message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Камера", style: .default, handler: { action in
self.showCamera()
}))
actionSheet.addAction(UIAlertAction(title: "Альбом ", style: .default, handler: {action in
self.showAlbum()
}))
actionSheet.addAction(UIAlertAction(title: "Отмена", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
And on wallpaperImageView tapping in handleSelectWallpaperImageView method set isProfilePhotoSelecting to false i.e.
#objc func handleSelectWallpaperImageView(sender: UIGestureRecognizer){
guard let sendingImageView = sender.view as? UIImageView else {
print("Ooops, received this gesture not from an ImageView")
return
}
// Updated the image under consideration
isProfilePhotoSelecting = false
let actionSheet = UIAlertController(title: "New Photo", message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Камера", style: .default, handler: { action in
self.showCamera()
}))
actionSheet.addAction(UIAlertAction(title: "Альбом ", style: .default, handler: {action in
self.showAlbum()
}))
actionSheet.addAction(UIAlertAction(title: "Отмена", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
Then update your imagePickerDelegate to :
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
if isProfilePhotoSelecting {
profilePhoto.image = image
} else {
wallpaperPhoto.image = image
}
}
dismiss(animated: true, completion: nil)
}
This will help you set both your images to their respective imageView. Then in saveTapped(_:) method you can check both imageViews for images and upload them i.e. Your saveTapped() method should look like this
#IBAction func saveTapped(_ sender: Any) {
let db = Firestore.firestore()
let did = Auth.auth().currentUser!.uid
let storageRef = Storage.storage().reference(forURL: "gs://crut-6c67c.appspot.com")
if let profileImage = self.profilePhoto.image, let imageData = profileImage.jpegData(compressionQuality: 0.1) {
let profileStorage = storageRef.child("profile_Image").child(did)
profileStorage.putData(imageData, metadata: nil, completion: {(metadata, Error) in
if Error != nil, metadata != nil {
return
}
profileStorage.downloadURL { (url: URL?,error: Error?) in
if let profileImageUrl = url?.absoluteString {
db.collection("suppliers").document("ip").collection("ipinfo").document(did).setData(["Profile Image":profileImageUrl], merge: true)
}
}
})
}
if let wallpaperImage = self.wallpaperPhoto.image, let imageData = wallpaperImage.jpegData(compressionQuality: 0.1) {
let wallpaperStorage = storageRef.child("wallpaper_Image").child(did)
wallpaperStorage.putData(imageData, metadata: nil, completion: {(metadata, Error) in
if Error != nil, metadata != nil {
return
}
wallpaperStorage.downloadURL { (url: URL?,error: Error?) in
if let wallpaperImageUrl = url?.absoluteString {
// Do your stuff with wallpaper image url here
}
}
})
}
let storyBoard: UIStoryboard = UIStoryboard(name: "Profile", bundle: nil)
let profileViewController = storyBoard.instantiateViewController(identifier:profile.Storyboard.profileViewController) as? ProfileViewController
self.view.window?.rootViewController = profileViewController
self.view.window?.makeKeyAndVisible()
}
Note: This will not wait for the images to upload as you are waiting for them to upload. But it depends on your usecase if you want to wait until the image uploading completes and then move to ProfileViewController, you can use DispatchGroup for that purpose.
I hope your saving the last choosen image on activeImageView and passing that to Firebase, hence only one image is getting uploaded.
Instead create and Array and both the images choosen from handleSelectWallpaperImageView and handleSelectWallpaperImageView, then loop through the Array and send to Firebase.
Check this for more information: https://stackoverflow.com/a/49934285/1244403
Created option Boolean variable
var isProfilePhotoSelecting:Bool?
#objc func handleSelectWallpaperImageView(sender: UIGestureRecognizer){
isProfilePhotoSelecting = false
///
other code
}
#objc func handleSelectProfileImageView(sender: UIGestureRecognizer){
isProfilePhotoSelecting = true
///
other code
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
dismiss(animated: true, completion: nil)
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage{
if isProfilePhotoSelecting == true {
profilePhoto.image = image
}else {
wallpaperPhoto.image = image
}
}
}
In the saveTapped need to be added storage references to each chosen image and its respective database.
#IBAction func saveTapped(_ sender: Any) {
let db = Firestore.firestore()
let did = Auth.auth().currentUser!.uid
let storageRef = Storage.storage().reference(forURL: "gs://crut-6c67c.appspot.com").child("profile_Image").child(did)
if let profileImage = self.profilePhoto.image, let imageData = profileImage.jpegData(compressionQuality: 0.1){
storageRef.putData(imageData, metadata: nil, completion: {(metadata, Error) in
if Error != nil, metadata != nil {
return
}
storageRef.downloadURL { (url: URL?, error: Error?) in
if let profileImageUrl = url?.absoluteString {
db.collection("suppliers").document("ip").collection("ipinfo").document(did).setData(["Profile Image":profileImageUrl], merge: true)
}
}
})
}
let wallStoreRef = Storage.storage().reference(forURL: "gs://crut-6c67c.appspot.com").child("Wallpaper_Image").child(did)
if let wallpaperImage = self.wallpaperPhoto.image, let imageData = wallpaperImage.jpegData(compressionQuality: 0.1) {
wallStoreRef.putData(imageData, metadata: nil, completion: {(metadata, Error) in
if Error != nil, metadata != nil {
return
}
wallStoreRef.downloadURL { (url: URL?,error: Error?) in
if let wallpaperImageUrl = url?.absoluteString {
// Do your stuff with wallpaper image url here
db.collection("suppliers").document("ip").collection("ipinfo").document(did).setData(["Wallpaper Image":wallpaperImageUrl], merge: true)
}
}
})
}
I use UIImagePickerController to take a photo by camera of iPhone.
I want to show both "take a photo" and "choose a photo".
My code
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
//imagePicker.sourceType = .PhotoLibrary
presentViewController(imagePicker, animated: true, completion: nil)
I tried to use imagePicker.sourceType = .Camera and imagePicker.sourceType = .PhotoLibrary together to do this, but it doesn't work...
Thank you
Import UIImagePickerControllerDelegate and create a variable to assign UIImagePickerController
var imagePicker = UIImagePickerController() and set imagePicker.delegate = self.
Create an action sheet to display options for 'Camera' and 'Photo library'.
On your button click action:
#IBAction func buttonOnClick(_ sender: UIButton)
{
self.btnEdit.setTitleColor(UIColor.white, for: .normal)
self.btnEdit.isUserInteractionEnabled = true
let alert = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { _ in
self.openCamera()
}))
alert.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { _ in
self.openGallary()
}))
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
/*If you want work actionsheet on ipad
then you have to use popoverPresentationController to present the actionsheet,
otherwise app will crash on iPad */
switch UIDevice.current.userInterfaceIdiom {
case .pad:
alert.popoverPresentationController?.sourceView = sender
alert.popoverPresentationController?.sourceRect = sender.bounds
alert.popoverPresentationController?.permittedArrowDirections = .up
default:
break
}
self.present(alert, animated: true, completion: nil)
}
func openCamera()
{
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerController.SourceType.camera))
{
imagePicker.sourceType = UIImagePickerController.SourceType.camera
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func openGallary()
{
imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
Download sample project for Swift, SwiftUI
Swift 5 +:
Action sheet with camera and gallery:
//MARK:- Image Picker
#IBAction func imagePickerBtnAction(selectedButton: UIButton)
{
let alert = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { _ in
self.openCamera()
}))
alert.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { _ in
self.openGallery()
}))
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
Camera image picker functionality:
func openCamera()
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerController.SourceType.camera
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
Gallery image picker functionality:
func openGallery()
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have permission to access gallery.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
ImagePicker delegate:
//MARK:-- ImagePicker delegate
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let pickedImage = info[.originalImage] as? UIImage {
// imageViewPic.contentMode = .scaleToFill
}
picker.dismiss(animated: true, completion: nil)
}
set delegate like:
UIImagePickerControllerDelegate,UINavigationControllerDelegate
take one imageview so we can display selected/captured image:
#IBOutlet weak var imageViewPic: UIImageView!
For capture new image by using device camera:
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)
}
For select photo from gallery:
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
This is the delegate method :
//MARK: - ImagePicker delegate
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
// imageViewPic.contentMode = .scaleToFill
imageViewPic.image = pickedImage
}
picker.dismiss(animated: true, completion: nil)
}
set permission for access camera and photo in info.plist like:
<key>NSCameraUsageDescription</key>
<string>This app will use camera</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>You can select photo</string>
100% working and tested
Create view controller and add button and image in the storyboard
add UIImagePickerControllerDelegate,UINavigationControllerDelegate protocols in view controller
camera action button enter following code
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let actionsheet = UIAlertController(title: "Photo Source", message: "Choose A Sourece", 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 is Not Available")
}
}))
actionsheet.addAction(UIAlertAction(title: "Photo Library", 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)
Add following function in view controller
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)
}
}
in info.plist add row with
Privacy - Photo Library Usage Description
Privacy - Camera Usage Description
I created this beautiful project and with these four lines of code you get image either from camera or library and apply beautiful filters with a single line like this : -
let picker = PickerController()
picker.applyFilter = true // to apply filter after selecting the picture by default false
picker.selectImage(self){ image in
// Use the picture
}
Here's the link of the project.
//MARK:- Camera and Gallery
func showActionSheet(){
//Create the AlertController and add Its action like button in Actionsheet
let actionSheetController: UIAlertController = UIAlertController(title: NSLocalizedString("Upload Image", comment: ""), message: nil, preferredStyle: .actionSheet)
actionSheetController.view.tintColor = UIColor.black
let cancelActionButton: UIAlertAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel) { action -> Void in
print("Cancel")
}
actionSheetController.addAction(cancelActionButton)
let saveActionButton: UIAlertAction = UIAlertAction(title: NSLocalizedString("Take Photo", comment: ""), style: .default)
{ action -> Void in
self.camera()
}
actionSheetController.addAction(saveActionButton)
let deleteActionButton: UIAlertAction = UIAlertAction(title: NSLocalizedString("Choose From Gallery", comment: ""), style: .default)
{ action -> Void in
self.gallery()
}
actionSheetController.addAction(deleteActionButton)
self.present(actionSheetController, animated: true, completion: nil)
}
func camera()
{
let myPickerControllerCamera = UIImagePickerController()
myPickerControllerCamera.delegate = self
myPickerControllerCamera.sourceType = UIImagePickerController.SourceType.camera
myPickerControllerCamera.allowsEditing = true
self.present(myPickerControllerCamera, animated: true, completion: nil)
}
func gallery()
{
let myPickerControllerGallery = UIImagePickerController()
myPickerControllerGallery.delegate = self
myPickerControllerGallery.sourceType = UIImagePickerController.SourceType.photoLibrary
myPickerControllerGallery.allowsEditing = true
self.present(myPickerControllerGallery, animated: true, completion: nil)
}
//MARK:- *************** UIImagePickerController delegate Methods ****************
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// The info dictionary may contain multiple representations of the image. You want to use the original.
guard let selectedImage = info[.originalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image.
imageUserProfile.image = selectedImage
// Dismiss the picker.
dismiss(animated: true, completion: nil)
}
Swift 5 Easy way just call function
//MARK Life Cycles
override func viewDidLoad() {
super.viewDidLoad()
choosePicture
}
extension AddBook: UIPickerViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#objc func choosePicture(){
let alert = UIAlertController(title: "Select Image", message: "", preferredStyle: .actionSheet)
alert.modalPresentationStyle = .overCurrentContext
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (action) in
self.openCamera()
}))
alert.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: { (action) in
self.openGallary()
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
let popoverController = alert.popoverPresentationController
popoverController?.permittedArrowDirections = .up
self.present(alert, animated: true, completion: nil)
}
func openCamera() {
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerController.SourceType.camera))
{
imagePicker.sourceType = UIImagePickerController.SourceType.camera
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func openGallary() {
imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
private func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// picker.supportedInterfaceOrientations = .
if let image = info[UIImagePickerController.InfoKey.originalImage.rawValue] as? UIImage {
if btnPicOther.tag == 1 {
btnPicOther.setImage(image, for: .normal)
}
else if btnPicBack.tag == 1 {
btnPicBack.setImage(image, for: .normal)
}
else if btnPicFront.tag == 1{
btnPicFront.setImage(image, for: .normal)
}
picker.dismiss(animated: true, completion: nil)
}
}
}
Swift 5: you may use the camera image below:
Create a project
In the main Storyboard, add two buttons in the bottom & add imageView & link to viewController.
Add Privacy - Camera Usage Description permission in Info.plist like below:
Paste below code in view controller:
class ViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnPhotGalary(_ sender: Any) {
let picker = UIImagePickerController()
picker.sourceType = .photoLibrary
picker.delegate = self
present(picker, animated: true)
}
#IBAction func btnCapture(_ sender: Any) {
let picker = UIImagePickerController()
picker.sourceType = .camera
//for camera front
// picker.cameraDevice = .front
picker.delegate = self
picker.allowsEditing = false
present(picker, animated: true)
}
}
extension ViewController :UIImagePickerControllerDelegate,UINavigationControllerDelegate{
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true, completion: nil)
guard let originalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
return
}
//for image rotation
let image = originalImage.upOrientationImage()
imageView.image = image
}
}
extension UIImage {
func upOrientationImage() -> UIImage? {
switch imageOrientation {
case .up:
return self
default:
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(in: CGRect(origin: .zero, size: size))
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return result
}
}
}
Full source is given in GitHub: https://github.com/enamul95/UIImagePicker.git
This will create a reusable class that will show an action sheet when your image, button, etc. is tapped.
import Foundation
import UIKit
class CameraHandler: NSObject{
static let shared = CameraHandler()
fileprivate var currentVC: UIViewController!
//MARK: Internal Properties
var imagePickedBlock: ((UIImage) -> Void)?
func camera()
{
if UIImagePickerController.isSourceTypeAvailable(.camera){
let myPickerController = UIImagePickerController()
myPickerController.delegate = self
myPickerController.allowsEditing = true
myPickerController.sourceType = .camera
currentVC.present(myPickerController, animated: true, completion: nil)
}
}
func photoLibrary()
{
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
let myPickerController = UIImagePickerController()
myPickerController.delegate = self
myPickerController.allowsEditing = true
myPickerController.sourceType = .photoLibrary
currentVC.present(myPickerController, animated: true, completion: nil)
}
}
func showActionSheet(vc: UIViewController) {
currentVC = vc
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (alert:UIAlertAction!) -> Void in
self.camera()
}))
actionSheet.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { (alert:UIAlertAction!) -> Void in
self.photoLibrary()
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
vc.present(actionSheet, animated: true, completion: nil)
}
}
extension CameraHandler: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// The info dictionary may contain multiple representations of the image. Since we said "allowsEditing = true" we need to set this to ".editedImage".
guard let selectedImage = info[.editedImage] as? UIImage else {
fatalError("“Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image.
self.imagePickedBlock?(selectedImage)
// Dismiss the picker.
currentVC.dismiss(animated: true, completion: nil)
}
}
TO USE IT
Make sure you set your info PList like this image below.
Create a storyboard with an UIImageView and drag imageView to ViewController. This will create a #IBOutlet like you see in the code below. I named my imageView profileImageView.
create a UIImage and set it to an image in your asset folder or use a system image. If using a system image it should look like this UIImage(systemName: "plus") NOTE: plus is an example pass whatever system image you like there.
(4) Create a function that updates the profileImageView to meet your needs, add the image to the profileImageView and then call this function in ViewDidLoad()
(5) In the same function I setup a tapGestureRecognizer so anytime the imageView it tapped it is notified and fires the editImageTapGesture() func.
(6) Setup the editImageTapGesture func to access the CameraHandler and show action sheet as well as assign the image (you select from library or take from camera) to your profileImageView.
import UIKit
class EditProfileImageController: UIViewController {
// (2) IBOutlet from storyboard
#IBOutlet weak var profileImageView: UIImageView!
// (3) Add image: this can be a system image or in my case an image in my assets folder named "noImage".
var profileImage = UIImage(named: "noImage")
override func viewDidLoad() {
super.viewDidLoad()
setupProfileImage()
}
//(4) I setup the profile image in this function and set profile image to the profileImageView
private func setupProfileImage() {
profileImageView.contentMode = .scaleAspectFill
profileImageView.image = profileImage
//(5) setup tap gesture for when profileImageView is tapped
profileImageView.isUserInteractionEnabled = true
let editImageTapGesture = UITapGestureRecognizer(target: self, action: #selector(editProfileImageTapped(_:)))
profileImageView.addGestureRecognizer(editImageTapGesture)
}
//(6) Once tap on profile image occurs the action sheet appears with Gallery and Camera buttons.
#objc func editProfileImageTapped(_ sender: UITapGestureRecognizer) {
CameraHandler.shared.showActionSheet(vc: self)
CameraHandler.shared.imagePickedBlock = { (image) in
self.profileImageView.image = image
}
}
}
Action Sheet should look like this:
I have a button to take an image . I wish to pass the image taken from camera to another view controller.The code for first viewcontroller is shown below.
#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])
{
TakenImage = info[UIImagePickerControllerOriginalImage] as? UIImage ; dismissViewControllerAnimated(true, completion: nil )
let controller = self.storyboard!.instantiateViewControllerWithIdentifier("NoteDetailViewController") as! NoteDetailViewController
controller.takinPhoto = true
if (note != "")
{
controller.content = note
}
controller.imageFromCamera = TakenImage
if (self.tags != "")
{
controller.tagsTextField.text = self.tags
}
self.presentViewController(controller, animated: true, completion: nil)
}
#IBAction func save(sender: AnyObject)
{
UIImageWriteToSavedPhotosAlbum(TakenImage!, self, "image:didFinishSavingWithError:contextInfo:", nil)
}
func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:UnsafePointer<Void>)
{
if error == nil {
let ac = UIAlertController(title: "Saved!", message: "Your altered image has been saved to your photos.", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
} else
{
let ac = UIAlertController(title: "Save error", message: error?.localizedDescription, preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
}
}
The code for my second viewcontroller is shown below
if (takinPhoto == true)
{
if (imageFromCamera != nil)
{
if let image1 = self.imageFromCamera
{
self.imageView2.image = image1
}
}
if (self.content != "")
{
self.contentTextField2.text = content
}
}
But image from camera is not appearing in the second viewcontroller.How can I solve this??
Updated answer.
I rewrote your code and was able to get it working locally. The main change was to use a different delegate method which is specific to photos.
#IBAction func takePhoto(sender: AnyObject) { let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .Camera
presentViewController(picker, animated: true,completion : nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
takenImage = image
dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func save(sender: AnyObject) {
UIImageWriteToSavedPhotosAlbum(takenImage!, self, #selector(ViewController.image(_:didFinishSavingWithError:contextInfo:)), nil)
}
func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:UnsafePointer<Void>) {
if error == nil {
let ac = UIAlertController(title: "Saved!", message: "Your altered image has been saved to your photos.", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
} else {
let ac = UIAlertController(title: "Save error", message: error?.localizedDescription, preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "saveTakenImage") {
let controller = segue.destinationViewController as! NoteDetailViewController
controller.takinPhoto = true
if (note != "") {
controller.content = note
}
controller.imageFromCamera = takenImage
if (self.tags != "") {
controller.tagsTextField.text = self.tags
}
}
}
I've tried to find proper answer but no success.
I have code as below which works fine (I can get picture from library) but image size I got always is <= device width.
To be precisely - image in device gallery is for example 4k and picked image is "UIImage: 0x7ce6a5e0> size {640, 480} orientation 0 scale 1.000000" for iPhone 4s
When I'm changing "self.imagePicker.allowsEditing = true" to "false" I got no image (nil).
My goal is to pick from library original size image.
Can someone help me ?
#IBAction func newButton(sender: UIButton) {
let alert: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
let SelectImage = UIAlertAction(title: NSLocalizedString("TakePhoto", comment: "comment"), style: .Default){ (action) in
if UIImagePickerController.availableCaptureModesForCameraDevice(.Rear) != nil {
self.imagePicker.allowsEditing = true
self.imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
self.imagePicker.cameraCaptureMode = .Photo
self.presentViewController(self.imagePicker, animated: true, completion: nil)
} else {
self.noCamera()
}
}
alert.addAction(SelectImage)
let chooseImage = UIAlertAction(title: NSLocalizedString("PhotoLibrary", comment: "comment"), style: .Default){ (action) in
self.imagePicker.allowsEditing = true
self.imagePicker.sourceType = .PhotoLibrary
self.presentViewController(self.imagePicker, animated: true, completion: nil)
}
alert.addAction(chooseImage)
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: "comment"), style: .Cancel, handler: nil)
alert.addAction(cancelAction)
self.presentViewController(alert, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let selectedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
print(selectedImage)
takenPhoto = cropToSquare(image: selectedImage)
Util.addRecord(takenPhoto)
}
dismissViewControllerAnimated(true, completion: nil)
performSegueWithIdentifier("saveToSettings", sender: self)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
I am developing a chat app. In my app when I click attachement button, two options should come.
1) images/videos captured by the device camera(not capturing image at that time. Fetch images taken by the camera that is stored in the device)
2) images/videos downloaded from the web or other medias
Is there any way to fetch images/videos according to the above given criteria preferably using assets library
class YourController : UIViewController,UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIActionSheetDelegate,UIPopoverPresentationControllerDelegate
{
override func viewDidLoad() {
super.viewDidLoad()
}
func takePhotoByGalleryOrCamera(){
//MAark Take picture from gallery and camera
//image picker controller to use take image
// uialert controller to make action
let imageController = UIImagePickerController()
imageController.editing = false
imageController.delegate = self;
let alert = UIAlertController(title: "", message: "Profile Image Selctor", preferredStyle: UIAlertControllerStyle.ActionSheet)
let libButton = UIAlertAction(title: "Select photo from library", style: UIAlertActionStyle.Default) { (alert) -> Void in
imageController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(imageController, animated: true, completion: nil)
}
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)){
let cameraButton = UIAlertAction(title: "Take a picture", style: UIAlertActionStyle.Default) { (alert) -> Void in
print("Take Photo")
imageController.sourceType = UIImagePickerControllerSourceType.Camera
self.presentViewController(imageController, animated: true, completion: nil)
}
alert.addAction(cameraButton)
} else {
print("Camera not available")
}
let cancelButton = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { (alert) -> Void in
print("Cancel Pressed")
}
alert.addAction(libButton)
alert.addAction(cancelButton)
if UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad {
alert.modalPresentationStyle = UIModalPresentationStyle.Popover;
// alert.transitioningDelegate = self;
alert.popoverPresentationController!.sourceView = self.view;
alert.popoverPresentationController!.sourceRect = CGRectMake(0, SizeUtil.screenHeight(), SizeUtil.screenWidth(), SizeUtil.screenHeight()*0.4)
alert.popoverPresentationController!.delegate = self;
self.presentViewController(alert, animated: true, completion: nil)
} else {
self.presentViewController(alert, animated: true, completion: nil)
}
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.Popover
}
//image picker Delegate
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
self.dismissViewControllerAnimated(true, completion: nil)
let header = profileTableView.headerViewForSection(0) as! ProfileHeaderView
header.btnImage.setImage(image, forState: UIControlState.Normal)
_userProfileImage = image
}
}