[英]How to make UIImagePickerController for camera and photo library at the same time in swift
I use UIImagePickerController to take a photo by camera of iPhone.我使用 UIImagePickerController 通过 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...我尝试同时使用imagePicker.sourceType =.Camera
和imagePicker.sourceType =.PhotoLibrary
来执行此操作,但它不起作用...
Thank you谢谢
Import UIImagePickerControllerDelegate
and create a variable to assign UIImagePickerController var imagePicker = UIImagePickerController()
and set imagePicker.delegate = self
.导入UIImagePickerControllerDelegate
并创建一个变量来分配 UIImagePickerController var imagePicker = UIImagePickerController()
并设置imagePicker.delegate = self
。
Create a 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(UIImagePickerControllerSourceType.camera))
{
imagePicker.sourceType = UIImagePickerControllerSourceType.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 = UIImagePickerControllerSourceType.photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
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: ImagePicker 委托:
//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:在info.plist 中设置访问相机和照片的权限,例如:
<key>NSCameraUsageDescription</key>
<string>This app will use camera</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>You can select photo</string>
100% working and tested 100% 工作和测试
Create view controller and add button and image in the storyboard创建视图控制器并在故事板中添加按钮和图像
add UIImagePickerControllerDelegate,UINavigationControllerDelegate protocols in view controller在视图控制器中添加 UIImagePickerControllerDelegate、UINavigationControllerDelegate 协议
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在 info.plist 添加行
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
}
//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 Swift 5 简单的方法只是调用函数
//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: Swift 5:您可以使用下面的相机图像:
Create a project创建项目
In the main Storyboard, add two buttons in the bottom & add imageView & link to viewController.在主 Storyboard 中,在底部添加两个按钮并添加 imageView 和链接到 viewController。
Add Privacy - Camera Usage Description permission in Info.plist like below:在Info.plist 中添加隐私 - 相机使用说明权限,如下所示:
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 } } }
This will create a reusable class that will show an action sheet when your image, button, etc. is tapped.这将创建一个可重复使用的 class,当您的图像、按钮等被点击时,它将显示一个操作表。
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.确保像下图一样设置信息 PList。
Create a storyboard with an UIImageView and drag imageView to ViewController.用 UIImageView 创建一个 storyboard 并将 imageView 拖到 ViewController。 This will create a @IBOutlet like you see in the code below.这将创建一个@IBOutlet,就像您在下面的代码中看到的那样。 I named my imageView profileImageView.我将我的 profileImageView 命名为 imageView。
create a UIImage and set it to an image in your asset folder or use a system image.创建一个 UIImage 并将其设置为资产文件夹中的图像或使用系统图像。 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.如果使用系统映像,它应该看起来像这样 UIImage(systemName: "plus") 注意:plus 是一个示例,传递您喜欢的任何系统映像。
(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() (4)创建一个更新profileImageView的function满足你的需求,将图片添加到profileImageView中然后在ViewDidLoad()中调用这个function
(5) In the same function I setup a tapGestureRecognizer so anytime the imageView it tapped it is notified and fires the editImageTapGesture() func. (5) 在同一个 function 中,我设置了一个 tapGestureRecognizer,因此只要 imageView 被点击它就会收到通知并触发 editImageTapGesture() 函数。
(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. (6) 设置 editImageTapGesture 函数以访问 CameraHandler 并显示操作表以及将图像(您 select 来自库或从相机拍摄)分配给您的 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
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.