Cannot assign value of type 'SignUpViewController' to type '(UIImagePickerControllerDelegate & UINavigationControllerDelegate)?' - swift

#objc func presentPicker(){
let picker = UIImagePickerController()
picker.sourceType = .photoLibrary
picker.allowsEditing = true
picker.delegate = self //error
self.present(picker, animated: true, completion: nil)
}
extension SignInViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(\_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: \[UIImagePickerController.InfoKey : Any\]) {
if let imageSelected = info\[UIImagePickerController.InfoKey.editedImage\] as? UIImage {
avatar.image = imageSelected}
if let imageOriginal = info[UIImagePickerController.InfoKey.originalImage] as?
UIImage {
avatar.image = imageOriginal
}
picker.dismiss(animated: true, completion: nil)
}
}
I think(!) I have copied the tutorial code correctly but get two errors in my ImagePicker struct
//Error: Cannot assign value of type 'SignUpViewController' to type '(UIImagePickerControllerDelegate & UINavigationControllerDelegate)?'
I'm using Xcode 13.

At line
picker.delegate = self
You have assigned SignUpViewController object to picker delegate and you have inherited UIImagePickerControllerDelegate into SignInViewController class instead of SignUpViewController
replace extension SignInViewController: with extension SignUpViewController:

Related

Select Video Instead of Image using ImagePickerController - Swift

My situation is that I have a working imagepickercontroller that allows the user to pick an image from their camera roll and display it on an imageview inside the application.
The problem is that I also want to be able to do the same thing with videos, and instead, display the video on an avplayer. I've done some research but couldn't find any good sources.
Can someone show me how to do this? possibly by editing the code below?
Thanks in advance!
This is the code I used for importing and displaying images from cameraroll (all above the viewDidLoad()):
#IBOutlet weak var imageView: UIImageView!
// the image picker controller
var imagePicker = UIImagePickerController()
// this is the button you tap to import your photo
#IBAction func imageViewButtonTapped(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum) {
imagePicker.delegate = self
imagePicker.allowsEditing = true
present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
var selectedImageFromPicker: UIImage?
if let editedImage = info[.editedImage] as? UIImage{
selectedImageFromPicker = editedImage
}else if let originalImage = info[.originalImage] as? UIImage{
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker {
imageView.image = selectedImage
}
dismiss(animated: true, completion: nil)
}
try this:
import AVFoundation
class VideoHelper {
static func startMediaBrowser(delegate: UIViewController & UINavigationControllerDelegate & UIImagePickerControllerDelegate, sourceType: UIImagePickerController.SourceType) {
guard UIImagePickerController.isSourceTypeAvailable(sourceType) else { return }
let mediaUI = UIImagePickerController()
mediaUI.sourceType = sourceType
mediaUI.mediaTypes = [kUTTypeMovie as String]
mediaUI.allowsEditing = true
mediaUI.delegate = delegate
delegate.present(mediaUI, animated: true, completion: nil)
}
}
and you can use this as:
let source = UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) ? UIImagePickerController.SourceType.camera : UIImagePickerController.SourceType.savedPhotosAlbum
VideoHelper.startMediaBrowser(delegate: self, sourceType: source)

UIImagePickerController didFinishPickingMediaWithInfo not being called with cameraOverlyView

I have UIImagePickerController with cameraOverlyView. I added tap gesture recognizer to the overlay view - when user taps on the view the recording should be stopped and saved:
let mediaUI = UIImagePickerController()
mediaUI.sourceType = sourceType
mediaUI.mediaTypes = [kUTTypeMovie as String]
mediaUI.allowsEditing = true
mediaUI.delegate = self
//customView stuff
let customViewController = CustomOverlayViewController(
nibName:"CustomOverlayViewController",
bundle: nil
)
let customView:CustomOverlayView = customViewController.view as! CustomOverlayView
customView.frame = delegate.view.frame //self.picker.view.frame
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(cameraViewTapped(tapGestureRecognizer:)))
customView.cameraView.addGestureRecognizer(tapGestureRecognizer)
customView.delegate = delegate
delegate.present(mediaUI, animated: true, completion: {
mediaUI.cameraOverlayView = customView
})
gesture recognizer calls this:
#objc func cameraViewTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
if isRecording {
self.picker!.stopVideoCapture()
self.recordButton.isEnabled = false
print("stopped")
isRecording = false
} else {
self.picker!.startVideoCapture()
print("started")
isRecording = true
}
}
delegate method:
extension HomeViewController: UIImagePickerControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) {
print("didFinishPickingMediaWithInfo")
dismiss(animated: true, completion: nil)
guard
let mediaType = info[UIImagePickerControllerMediaType] as? String,
mediaType == (kUTTypeMovie as String),
let url = info[UIImagePickerControllerMediaURL] as? URL,
UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(url.path)
else {
return
}
// Handle a movie capture
UISaveVideoAtPathToSavedPhotosAlbum(
url.path,
self,
#selector(video(_:didFinishSavingWithError:contextInfo:)),
nil)
}
}
My question is how to get recording from the picker controller? Delegate method didFinishPickingMediaWithInfo is not called because of the overlay view: UIImagePickerController didFinishPickingMediaWithInfo not being called when cameraOverlyView property is assigned
Solved the issue by adding the following line of code:
mediaUI.showsCameraControls = false

Creating an image format with an unknown type is an error while capturing image from gallery Swift

Im trying to get image from gallery in Swift.
func showPicker(type : UIImagePickerControllerSourceType) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = type
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
then:
self.showPicker(type: .savedPhotosAlbum)
However, when i enter gallery on my device and pick photo nothing happen, instead in log it says : [Generic] Creating an image format with an unknown type is an error
How to dismiss gallery and save image?
UIImagepickerView
set delegate UIImagePickerControllerDelegate, UINavigationControllerDelegate
let imagePicker = UIImagePickerController()
//in did load
imagePicker.delegate = self
// MARK: - UIImagePickerControllerDelegate Methods
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
imgview.image = image
} else{
print("Something went wrong")
}
dismiss(animated: true, completion: nil)
}

Set image of UIImageView using gestureRecognizer

I am asking if it is possible to set the image of a UIImageView using a gestureRecognizer, or is it necessary to overlay a button on top of the UIImageView.
I have an outlet collection of UIImageViews, called imageViews. There are four of these, and their tags have been set from 1 to 4. In my viewDidLoad, to add the gesture recognizer to each of the image views in the collection, i have used:
override func viewDidLoad() {
super.viewDidLoad()
for i in (0..<imageViews.count) {
let imageViewTapped = UITapGestureRecognizer(target: self, action: #selector(selectImage(tap:)))
imageViewTapped.numberOfTapsRequired = 1
imageViews[i].addGestureRecognizer(imageViewTapped)
}
}
Next, I created my gestureRecognizer as a function in the viewController class. This is where the image picker controller is created and where the image view that was tapped is identified:
func selectImage(tap: UITapGestureRecognizer) {
var imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = false
imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
self.present(imagePicker, animated: true, completion: nil)
guard let viewTappedTag = tap.view?.tag else {return}
self.selectedImageView = imageViews[viewTappedTag - 1]
}
selectedImageView is a variable in the viewController class with a type of UIImageView. My thinking was that this variable could hold the UIImageView that was tapped, which is identified by the gestureRecognizer, as shown above. This could then be passed to the delegate later on.
Next, I created the delegates, the didFinishPickingMediaWithInfo and didCancel, though I will only show the former for brevity. Both were created inside the viewController class:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
self.selectedImageView.image = chosenImage
dismiss(animated: true, completion: nil)
}
Unfortunatley, the image of the image view that was tapped is not updated to the one that was chosen from the library. What is the correct way to do this? And I feel as though I am bloating my viewController with all of this code, can this be moved to a seperate class? Am i wrong in doing it like this, and instead one should just overlay a button?
EDIT
The best I could come up with so far is a switch statement in my imagePickerController, where imageViewOne, imageViewTwo etc are outlets for each UIImageView:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
switch self.viewTappedTag {
case 1:
imageViewOne.image = chosenImage
case 2:
imageViewTwo.image = chosenImage
case 3:
imageViewThree.image = chosenImage
case 4:
imageViewFour.image = chosenImage
default:
imageViewOne.image = chosenImage
}
dismiss(animated: true, completion: nil)
}
where viewTappedTag is a viewController class variable, the value of which is defined by the tag of the view that was tapped and is set in the gestureRecognizer. Can anyone improve on this?
Update the code as following
Declare a variable in the class as follows
var selectedImageViewIndex = 0 //by default selected image view is 0th image view
func selectImage(tap: UITapGestureRecognizer) {
var imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = false
imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
self.present(imagePicker, animated: true, completion: nil)
guard let viewTappedTag = tap.view?.tag else {return}
self.selectedImageView = imageViews[viewTappedTag - 1]
//Add the following line
self.selectedImageViewIndex = viewTappedTag - 1
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
self.selectedImageView.image = chosenImage
//Add the following line
self.imageView[self.selectedImageViewIndex].image = chosenImage
dismiss(animated: true, completion: nil)
}
Though I would advice not to use viewTappedTag - 1 and instead get the value of index and tapped image tag from a mapped object.
In the end I used a switch statement to achieve my goal:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
switch self.viewTappedTag {
case 1:
imageViewOne.image = chosenImage
case 2:
imageViewTwo.image = chosenImage
case 3:
imageViewThree.image = chosenImage
case 4:
imageViewFour.image = chosenImage
default:
imageViewOne.image = chosenImage
}
dismiss(animated: true, completion: nil)
}

UIImagePickerController Gallery delegate is not calling

I am using UIImagePickerController with this code
func openCamera()
{
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
{
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.Camera
picker.cameraCaptureMode = .Photo
picker.modalPresentationStyle = .FullScreen
presentViewController(picker,
animated: true,
completion: nil)
}
else
{
openGallary()
}
}
func openGallary()
{
let menuViewController = UIImagePickerController()
menuViewController.modalPresentationStyle = .Popover
menuViewController.preferredContentSize = CGSizeMake(320, 320 )
//menuViewController.tableView = FrontTable
let popoverMenuViewController = menuViewController.popoverPresentationController
popoverMenuViewController?.permittedArrowDirections = .Any
popoverMenuViewController?.delegate = self
popoverMenuViewController?.sourceView = flagBtn
popoverMenuViewController?.sourceRect = CGRect(
x: 15,
y: 25,
width: 1,
height: 1)
presentViewController(
menuViewController,
animated: true,
completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
picker .dismissViewControllerAnimated(true, completion: nil)
let image=info[UIImagePickerControllerOriginalImage] as? UIImage
flagBtn.setImage(image, forState: .Normal)
flagBtn.setImage(image, forState: .Highlighted)
flagBtn.setImage(image, forState: .Selected)
}
With camera delegate is working fine but with gallery delegate is not working. For camera I have define the "picker" variable in the class and define it's delegate self in "Viewdidload". I have also tried to use picker variable in openGallary function but it is also not working.
I think these 2 lines might help:
menuViewController.delegate = self
menuViewController.sourceType = .PhotoLibrary
Make sure you have added UINavigationControllerDelegate and UIImagePickerControllerDelegate to your ViewController.