Display two images in didFinishPickingImage - iOS Swift 2.2 [duplicate] - ios

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
}
}

Related

Saving photo to image in Swift 4.2

I am having a problem displaying the photo I just took or chose to the image view.
Below is a pic of the imagview on the left and the licencePhoto button on right.
When I click on Take Photo, it allows me to take a pic or select from my library, as the code shows:
#IBAction func seclectOrTakePhoto(_ sender: Any) {
pickerController.delegate = self
pickerController.allowsEditing = true
let alertController = UIAlertController(title: "Add a Picture", message: "Choose From", preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: .default) { (action) in
self.pickerController.sourceType = .camera
self.present(self.pickerController, animated: true, completion: nil)
}
let photosLibraryAction = UIAlertAction(title: "Photos Library", style: .default) { (action) in
self.pickerController.sourceType = .photoLibrary
self.present(self.pickerController, animated: true, completion: nil)
}
let savedPhotosAction = UIAlertAction(title: "Saved Photos Album", style: .default) { (action) in
self.pickerController.sourceType = .savedPhotosAlbum
self.present(self.pickerController, animated: true, completion: nil)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)
alertController.addAction(cameraAction)
alertController.addAction(photosLibraryAction)
alertController.addAction(savedPhotosAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
But, it does not display the photo to the licensePhoto image and in Firebase, it is uploading the pic I have displayed in the image view as below and not the one I just took with phone.
How can I achieve this?
Edited
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
self.licensePhoto.image = image
self.dismiss(animated: true, completion: nil)
// any time the photo changes, check the button status
updateSignupButtonStatus()
}
After searching and looking through tutorials, I finally got something to work:
#objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
licensePhoto.contentMode = .scaleAspectFit
licensePhoto.image = chosenImage
pickerController.dismiss(animated: true, completion: nil)
}

Move and scale on UIImagePickerController

I am trying to allow the user to edit an existing photo using the move and scale view and allow them to edit any picture they pick or take but I can't get the move and scale view to appear correctly. How do I get the title and circle view to show? This is what it looks like now:
and this is what I want:
func addImage(sender: UIButton) {
self.view.endEditing(true)
let alert = UIAlertController(title: "", message: nil, preferredStyle: .actionSheet)
var numberAlert = UIAlertAction(title: "Take Photo", style: UIAlertActionStyle.default, handler: { action in
self.takePhoto()
})
alert.addAction(numberAlert)
numberAlert = UIAlertAction(title: "Choose Photo", style: UIAlertActionStyle.default, handler: { action in
self.choosePhoto()
})
alert.addAction(numberAlert)
numberAlert = UIAlertAction(title: "Edit Photo", style: UIAlertActionStyle.default, handler: { action in
self.editPhoto()
})
alert.addAction(numberAlert)
numberAlert = UIAlertAction(title: "Delete Photo", style: UIAlertActionStyle.default, handler: { action in
self.deletePhoto()
})
alert.addAction(numberAlert)
let cancelAlert = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default, handler:nil)
cancelAlert.setValue(UIColor.blue, forKey: "titleTextColor")
alert.addAction(cancelAlert)
self.present(alert, animated: true, completion: nil)
}
func choosePhoto() {
imagePicker = nil
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
imagePicker.sourceType = .photoLibrary
present(imagePicker, animated: true, completion: nil)
}
func takePhoto() {
imagePicker = nil
imagePicker = UIImagePickerController()
imagePicker.resignFirstResponder()
imagePicker.delegate = self
imagePicker.allowsEditing = true
imagePicker.sourceType = .camera
present(imagePicker, animated: true, completion: nil)
}
func editPhoto() {
}
func deletePhoto() {
}
//MARK: - Saving Image here
#IBAction func save(_ sender: AnyObject) {
UIImageWriteToSavedPhotosAlbum(self.contact.image!, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
}
//MARK: - Add image to Library
func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
NSLog("Error saving image: \(error)")
} else {
self.tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: UITableViewRowAnimation.none)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
imagePicker.dismiss(animated: true, completion: nil)
self.contact.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: UITableViewRowAnimation.none)
}

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.
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:

Why is my keyboard being loaded whenever I load my UIImagePickerController view?

I have a UIActionSheet for selecting between the camera or the photo library to embed an image into a UITextView but for whatever reason it's loading the keyboard. I force close the keyboard on press of the left button of the bar surrounding the UITextView but when I press photo library I opens and closes the keyboard before pushing to the image picker VC.
override func didPressLeftButton(sender: AnyObject?) {
let cameraMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
let photoLibrary = UIAlertAction(title: "Photo Library", style: .Default, handler: { (UIAlertAction) in
self.openPhotoLibrary()
})
let takePhoto = UIAlertAction(title: "Open Camera", style: .Default, handler: { (UIAlertAction) in
self.textView.endEditing(true)
self.openCamera()
})
let cancel = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
cameraMenu.addAction(photoLibrary)
cameraMenu.addAction(takePhoto)
cameraMenu.addAction(cancel)
self.presentViewController(cameraMenu, animated: true, completion: nil)
}
func openPhotoLibrary() {
imagePicker.sourceType = .PhotoLibrary
imagePicker.allowsEditing = false
presentViewController(imagePicker, animated: true, completion: nil)
}
func openCamera(){
imagePicker.sourceType = .Camera
imagePicker.showsCameraControls = true
presentViewController(imagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
// Image resizing
let textViewWidth: CGFloat = self.textView.frame.size.width - 20
let percentResize = textViewWidth / pickedImage.size.width
let toBeExportedHeight = pickedImage.size.height * percentResize
let resizedImage = ImageManipulationManager.sharedInstance.resizeImage(exportedWidth: Int(textViewWidth),exportedHeight: Int(toBeExportedHeight), originalImage: pickedImage)
// Storage into TextView
let attachment = NSTextAttachment()
attachment.image = resizedImage
let attString = NSAttributedString(attachment: attachment)
textView.textStorage.insertAttributedString(attString, atIndex: textView.selectedRange.location)
pastedImageLocations.append(textView.selectedRange.location)
textView.selectedRange.location = textView.selectedRange.location + 1
textView.textStorage.insertAttributedString(NSAttributedString(string: "\n"), atIndex: textView.selectedRange.location)
textView.selectedRange.location = textView.selectedRange.location + 1
textView.font = UIFont.systemFontOfSize(16.0)
// Image Caching
if let data = UIImageJPEGRepresentation(pickedImage, 0.50) {
socketMessages.append(["data": data])
haneke.set(value: data, key: String(unsafeAddressOf(attachment.image!)))
print("Image cached as \"\(String(unsafeAddressOf(attachment.image!)))\"")
}
}
dismissViewControllerAnimated(true, completion: nil)
self.textView.becomeFirstResponder()
}
Found the solution.
I had to change
dismissViewControllerAnimated(true, completion: nil)
self.textView.becomeFirstResponder()
to
dismissViewControllerAnimated(true) {
self.textView.becomeFirstResponder()
}
You can do some changes by adding this -
override func didPressLeftButton(sender: AnyObject?) {
let cameraMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
let photoLibrary = UIAlertAction(title: "Photo Library", style: .Default, handler: { (UIAlertAction) in
self.view.endEditing(true) //**------ Add this
self.openPhotoLibrary()
})
let takePhoto = UIAlertAction(title: "Open Camera", style: .Default, handler: { (UIAlertAction) in
self.view.endEditing(true) //**------ Add this
self.openCamera()
})
let cancel = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
cameraMenu.addAction(photoLibrary)
cameraMenu.addAction(takePhoto)
cameraMenu.addAction(cancel)
self.presentViewController(cameraMenu, animated: true, completion: nil)
}

How to fetch camera based and media based images/videos separately to display in collection view in iOS device

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
}
}

Resources