Related
I'm trying to access both the camera and photo library in swift4 using the following code
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let alert = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action: UIAlertAction) in
imagePickerController.sourceType = .camera
print(1)
}))
alert.addAction(UIAlertAction(title: "Photo Album", style: .default, handler: {(action: UIAlertAction) in
imagePickerController.sourceType = .photoLibrary
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
but it's not working. I'm not get an access authorization request even though I made sure that the plist has the camera and photo library authorization. I manipulate the code a bit to the following
AVCaptureDevice.requestAccess(for: AVMediaType.video) { response in
}
let photos = PHPhotoLibrary.authorizationStatus()
if photos == .notDetermined {
PHPhotoLibrary.requestAuthorization({status in
})
}
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let alert = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action: UIAlertAction) in
imagePickerController.sourceType = .camera
print(1)
}))
alert.addAction(UIAlertAction(title: "Photo Album", style: .default, handler: {(action: UIAlertAction) in
imagePickerController.sourceType = .photoLibrary
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
Now I am getting the authorization request for both cameras and photo library and I can see the AlertView but when I press camera or Photo Album as shown in the picture nothing happens.
I tried on a device and simulator for the camera.
Here is the code to load image from photos & camera in iOS.
⁃ You need to create an outlet of your UIImageView
⁃ Then add a tap gesture on to image view
⁃ Then connect tap gesture with the didTapOnImageView function.
⁃ Then add the following extension to your view controller.
//MARK:- Image Picker
extension YourViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//This is the tap gesture added on my UIImageView.
#IBAction func didTapOnImageView(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?.profileImgView.image = image
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
Note: Don't forget to add the privacy settings in info.plist
Privacy - Camera Usage Description
Privacy - Photo Library Usage Description
First of all, you need to import these libraries:
import Photos
import UIKit
#IBOutlet weak var loadPhoto: UIButton!
And you need setup delegates:
class YourClass: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UNUserNotificationCenterDelegate
func displayUploadImageDialog(btnSelected: UIButton) {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
let alertController = UIAlertController(title: "", message: "Upload profile photo?".localized(), preferredStyle: .actionSheet)
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: "Cancel action"), style: .cancel, handler: {(_ action: UIAlertAction) -> Void in
alertController.dismiss(animated: true) {() -> Void in }
})
alertController.addAction(cancelAction)
let cameraRollAction = UIAlertAction(title: NSLocalizedString("Open library".localized(), comment: "Open library action"), style: .default, handler: {(_ action: UIAlertAction) -> Void in
if UI_USER_INTERFACE_IDIOM() == .pad {
OperationQueue.main.addOperation({() -> Void in
picker.sourceType = .photoLibrary
self.present(picker, animated: true) {() -> Void in }
})
}
else {
picker.sourceType = .photoLibrary
self.present(picker, animated: true) {() -> Void in }
}
})
alertController.addAction(cameraRollAction)
alertController.view.tintColor = .black
present(alertController, animated: true) {() -> Void in }
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
profileImage.image = image
let imageData = UIImageJPEGRepresentation(image, 0.05)
self.dismiss(animated: true, completion: nil)
}
func checkPermission() {
let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
switch authStatus {
case .authorized:
self.displayUploadImageDialog(btnSelected: self.loadPhoto)
case .denied:
print("Error")
default:
break
}
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
func checkLibrary() {
let photos = PHPhotoLibrary.authorizationStatus()
if photos == .authorized {
switch photos {
case .authorized:
self.displayUploadImageDialog(btnSelected: self.loadPhoto)
case .denied:
print("Error")
default:
break
}
}
}
Setup action for button:
#IBAction func loadPhotoTapped(_ sender: UIButton) {
let photos = PHPhotoLibrary.authorizationStatus()
if photos == .notDetermined {
PHPhotoLibrary.requestAuthorization({status in
if status == .authorized{
print("OKAY")
} else {
print("NOTOKAY")
}
})
}
checkLibrary()
checkPermission()
}
At the Info.plist setup the permissions:
Privacy - Media Library Usage Description
Privacy - Photo Library Usage Description
Privacy - Camera Usage Description
This should work.
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:
This code allows access to my photo gallery on the iPhone simulator in Xcode. When I put it on my iPad I can access the camera but not the photo gallery. I would like the image view to display the camera photos if choose or load a image from the photo gallery if choose.
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let picker = UIImagePickerController()
#IBOutlet weak var iv: UIImageView!
#IBAction func cameraf(_ sender: UIBarButtonItem) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.camera
picker.cameraCaptureMode = .photo
picker.modalPresentationStyle = .fullScreen
present(picker,animated: true,completion: nil)
} else {
noCamera()
}}
#IBAction func photolibaryss(_ sender: UIBarButtonItem) {
picker.allowsEditing = false
picker.sourceType = .photoLibrary
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
picker.modalPresentationStyle = .popover
present(picker, animated: true, completion: nil)
picker.popoverPresentationController?.barButtonItem = sender
}
func noCamera(){
let alertVC = UIAlertController(
title: "No Camera",
message: "Sorry, this device has no camera",
preferredStyle: .alert)
let okAction = UIAlertAction(
title: "OK",
style:.default,
handler: nil)
alertVC.addAction(okAction)
present(
alertVC,
animated: true,
completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
iv.contentMode = .scaleAspectFit
iv.image = chosenImage
dismiss(animated:true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}}
Update to the answer above. It works great, but has a few typos - need closing parentheses on addActions. Xcode 8.2 also changed presentViewController to present.
let alert = UIAlertController(title: nil, message: "Choose your source", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default) { (result : UIAlertAction) -> Void in
print("Camera selected")
//Code for Camera
//cameraf
})
alert.addAction(UIAlertAction(title: "Photo library", style: UIAlertActionStyle.Default) { (result : UIAlertAction) -> Void in
print("Photo selected")
//Code for Photo library
//photolibaryss
})
self.present(alert, animated: true, completion: nil)
You can make a UIAlertController which would consist of two alert actions photo library and camera, and then add the functions lines of code from photolibaryss and cameraf to respective alert actions.
let alert = UIAlertController(title: nil, message: "Choose your source", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default) { (result : UIAlertAction) -> Void in
print("Camera selected")
//Code for Camera
//cameraf
})
alert.addAction(UIAlertAction(title: "Photo library", style: UIAlertActionStyle.Default) { (result : UIAlertAction) -> Void in
print("Photo selected")
//Code for Photo library
//photolibaryss
})
self.present(alert, animated: true, completion: nil)
This question already has an answer here:
Picking two different images in the same view controller using imagePickerController in Swift
(1 answer)
Closed 6 years ago.
I have two UIImageViews, each with two buttons. One button takes a picture and the other chooses a photo from a library. Both buttons work correctly. But when I choose an image by a button from the first sheet, it is displayed in both UIImageViews. My question is how can we display the image in only the corresponding ImageView?.
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [NSObject : AnyObject]?) {
print("Image Selected")
self.dismissViewControllerAnimated(true, completion: nil)
importedImage.image = image
secondPhoto.image = image
}
// MARK: - Action Sheet
#IBAction func showActionSheet1(sender: AnyObject) {
let image = UIImagePickerController()
image.delegate = self
let actionSheet = UIAlertController(title: "Action Sheet", message: "Choose Option", preferredStyle: .ActionSheet)
let libButton = UIAlertAction(title: "Select from photo library", style: .Default, handler: { (libButton) -> Void in
image.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
image.allowsEditing = false
self.presentViewController(image, animated: true, completion: nil)
})
let cameraButton = UIAlertAction(title: "Take picture", style: .Default, handler: { (cameraButton) -> Void in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera){
image.sourceType = UIImagePickerControllerSourceType.Camera
image.allowsEditing = false
self.presentViewController(image, animated: true, completion: nil)
}
})
let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: {(cancelButton) -> Void in
print("Cancel selected")
})
actionSheet.addAction(libButton)
actionSheet.addAction(cameraButton)
actionSheet.addAction(cancelButton)
self.presentViewController(actionSheet, animated: true, completion: nil)
}
#IBAction func showActionSheet2(sender: AnyObject) {
let image = UIImagePickerController()
image.delegate = self
let actionSheet = UIAlertController(title: "Action Sheet", message: "Choose Option", preferredStyle: .ActionSheet)
let libButton = UIAlertAction(title: "Select from photo library", style: .Default, handler: { (libButton) -> Void in
image.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
image.allowsEditing = false
self.presentViewController(image, animated: true, completion: nil)
})
let cameraButton = UIAlertAction(title: "Take picture", style: .Default, handler: { (cameraButton) -> Void in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera){
image.sourceType = UIImagePickerControllerSourceType.Camera
image.allowsEditing = false
self.presentViewController(image, animated: true, completion: nil)
}
})
let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: {(cancelButton) -> Void in
print("Cancel selected")
})
actionSheet.addAction(libButton)
actionSheet.addAction(cameraButton)
actionSheet.addAction(cancelButton)
self.presentViewController(actionSheet, animated: true, completion: nil)
}
This is happening because you are setting image in both the ImageView inside didFinishPickingImage, to solve the issue need to maintain some state like which Button is clicked to set Image, for that you can create one Bool instance and assign its value inside the action of Button like this.
var isFromFirst: Bool = false
#IBAction func showActionSheet1(sender: AnyObject) {
self.isFromFirst = true
...//your other code
}
#IBAction func showActionSheet2(sender: AnyObject) {
self.isFromFirst = false
...//your other code
}
After that check this bool value inside didFinishPickingImage like this.
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [NSObject : AnyObject]?) {
print("Image Selected")
self.dismissViewControllerAnimated(true, completion: nil)
if (self.isFromFirst) {
importedImage.image = image
}
else {
secondPhoto.image = image
}
}
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
}
}
}