Memory leaks when using UIImagePickerController in camera mode - swift

This is a simple single view, single ViewController test app. This app has one button in the ViewController. Accessing the PhotoLibrary does not show any leaks, but the camera shows some leaks when presented and more when dismissed.
Here is code:
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let pickerCntrl = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
pickerCntrl.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func takePic(_ sender: Any) {
pickerCntrl.sourceType = UIImagePickerControllerSourceType.camera
pickerCntrl.cameraCaptureMode = .photo
pickerCntrl.allowsEditing = true
if (UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)){
self.present(pickerCntrl, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// let editedCapture = info[UIImagePickerControllerEditedImage] as! UIImage?
// let origCapture = info[UIImagePickerControllerOriginalImage] as! UIImage?
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
}
ScreenShot :

Related

How to add 2 or more images into email from photo gallery to MFMailComposeViewController [duplicate]

I am making an app in which there are two UIImageViews. In each image view the user needs to be able to input a different image. Here is the code I have so far.
var imagePicker = UIImagePickerController()
#IBAction func chooseImage1(sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.SavedPhotosAlbum){
println("Button capture")
imagePicker.delegate = self
imagePicker.sourceType = .SavedPhotosAlbum
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
#IBAction func chooseImage2(sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.SavedPhotosAlbum){
println("Button capture")
imagePicker2.delegate = self
imagePicker2.sourceType = .SavedPhotosAlbum
imagePicker2.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
chooseImage1.image = pickedImage
let pickedImage2 = info[UIImagePickerControllerOriginalImage] as? UIImage
chooseImage2.image = pickedImage2
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
This ends up picking the same image for each different image view. I would like to be able to choose two individual photos, one for each view. Thank you for your help.
You only need one UIImagePickerController. You can keep a reference of the tapped view and when the user finish picking the image, you just need to cast the selected view as UIImageView and set its image property:
update: Xcode 11.5 • Swift 5.2 or later
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate ,UINavigationControllerDelegate {
#IBOutlet weak var imageView1: UIImageView!
#IBOutlet weak var imageView2: UIImageView!
var imagePicker = UIImagePickerController()
var selectedVew: UIView!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
imagePicker.sourceType = .savedPhotosAlbum
imagePicker.allowsEditing = false
[imageView1,imageView2].forEach {
$0?.isUserInteractionEnabled = true
$0?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(chooseImage)))
}
}
#objc func chooseImage(_ gesture: UITapGestureRecognizer) {
if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum) {
selectedVew = gesture.view
present(imagePicker, animated: true)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
(selectedVew as? UIImageView)?.image = info[.originalImage] as? UIImage
dismiss(animated: true)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true)
}
}

Use of unresolved identifier with an image view

Im trying to make a pick selecter but I get Use unresolved identifier 'imageusr' . I tried changing the Target Membership and with that I get a lot more errors. imageusr.image = image ( here its where it shows the error )
Import UIkit class ViewController2: UIViewController {
#IBOutlet weak var imageusr: UIImageView!
var imagepick = UIImagePickerController()
#IBAction func seleccionar(_ sender: Any) {
imagepick.sourceType = .photoLibrary
imagepick.allowsEditing = true
present(imagepick, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
imageusr.roundedImage()
imagepick.delegate = (self as! UIImagePickerControllerDelegate & UINavigationControllerDelegate)
// Do any additional setup after loading the view.
} here
enter extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage{
imageusr.image = image
}
dismiss(animated: true, completion: nil)
}
}
Looks like it's a code alignment issue, the extension should be declared outside of the class
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var imageusr: UIImageView!
var imagepick = UIImagePickerController()
#IBAction func seleccionar(_ sender: Any) {
imagepick.sourceType = .photoLibrary
imagepick.allowsEditing = true
present(imagepick, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
imageusr.roundedImage()
imagepick.delegate = self
// Do any additional setup after loading the view.
}
}
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage{
imageusr.image = image
}
dismiss(animated: true, completion: nil)
}
}

How to filter extension in photoLibrary UIimgaePickerController swift

I only want in the library there are one types of video. Use default library. My app is currently taking images and videos from the application document directory using UIImagePickerController (.photoLibrary). I want to show just one video type .mp4
import AVFoundation
import MobileCoreServices
import Photos
import UIKit
class CameraLibraryTestViewController: UIViewController {
#IBOutlet weak var imgView: UIImageView!
let picker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func bAction(_ sender: Any) {
picker.mediaTypes = ["public.image", "public.mp4"] // filter extesion mp4 didn't work,
picker.sourceType = .photoLibrary
picker.allowsEditing = false
picker.delegate = self
present(picker, animated: true)
}
}
extension CameraLibraryTestViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
viewController.navigationItem.title = "Jeri Library"
picker.setEditing(false, animated: true)
print("test or check: \(viewController.debugDescription)")
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {
let assetPath = info[UIImagePickerControllerReferenceURL] as! NSURL
if (assetPath.absoluteString?.hasSuffix("MOV"))! {
print("MOV")
dismiss(animated: true) {
self.navigationController?.pushViewController(EmojiReadViewController(), animated: true)
}
}
else if (assetPath.absoluteString?.hasSuffix("MP4"))! {
print("MP4")
dismiss(animated: true) {
self.navigationController?.pushViewController(EmojiReadViewController(), animated: true)
}
}
else if (assetPath.absoluteString?.hasSuffix("M4V"))! {
print("M4V")
dismiss(animated: true) {
self.navigationController?.pushViewController(EmojiReadViewController(), animated: true)
}
}
else {
print("Unknown")
dismiss(animated: true, completion: nil)
}
}
}
I tried to use mediaType [kUTTypeMPEG4 as String] but it still doesn't work, which is in didFinishPickingMediaWithInfo it's only for filters after selecting from the library.
If I use kUTTypeMovie it gets all the videos on local storage
This will display only videos
picker.mediaTypes = [ "public.movie"]

Segue from a UICollectionReusableView to ImagePicker

I have a class for my UICollectionReusableView, but I need a button in that view to perform a segue from the UICollectionView to an imagePicker. I have tried to use a delegate, but I keep on getting nil for the delegate.
protocol ShouldSegueToImagePickerDelegate{
func shouldSegue()
}
class ProfileHeaderCollectionReusableView: UICollectionReusableView{
var delegate: ShouldSegueToImagePickerDelegate!
#IBAction func pressedChangeBGPicButton(sender: AnyObject) {
delegate.shouldSegue()
}
class ProfileCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, ShouldSegueToImagePickerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
var imagePicker = UIImagePickerController()
func shouldSegue() {
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
self.presentViewController(imagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
imagePicker.dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
imagePicker.dismissViewControllerAnimated(true, completion: nil)
}

Passing class via delegate : property not updated

don't understand why I didn't get my class property updated (imageData property).
simple example, 2 view controllers embed in navigation controller (important for me):
first one : ViewController with an imageView and a button to the second view controller (via segue)
class ViewController: UIViewController, choosePicVCDelegate {
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.imageView.clipsToBounds = true
}
func goodPic(vc: choosePicViewController) {
if let data = vc.imageData {
let image = UIImage(data: data)
self.imageView.image = image
}
vc.navigationController?.popViewControllerAnimated(true)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let vc = segue.destinationViewController as! choosePicViewController
vc.delegate = self
}
}
second one : choosePicViewController with an imagePicker to choose the image to display in the first ViewController. 2 buttons: one to choose the image, the other to go back to the first view controller with the delegate..
protocol choosePicVCDelegate {
func goodPic(vc: choosePicViewController)
}
class choosePicViewController: UIViewController {
var delegate: choosePicVCDelegate?
let imagePicker = UIImagePickerController()
var imageData: NSData?
#IBAction func back(sender: UIButton) {
delegate?.goodPic(self)
}
#IBAction func coverPick(sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary;
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
}
extension choosePicViewController: UIImagePickerControllerDelegate {
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
self.imageData = UIImageJPEGRepresentation(image, 1.0)
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
}
always got nil from imageData property, don't understand why.
I think the problem is your extension, i didn't understand why use extension in this case, whatever. Try do it.
You need set delegate from imagePicker.delegate = self, because with this you can listener the UIImagePickerController delegate. I believe with this you resolve.
protocol choosePicVCDelegate {
func goodPic(vc: choosePicViewController)
}
class choosePicViewController: UIViewController, UIImagePickerControllerDelegate {
var delegate: choosePicVCDelegate?
let imagePicker = UIImagePickerController()
var imageData: NSData?
override func viewWillAppear(animated: Bool) {
imagePicker.delegate = self;
}
override func viewDidDisappear(animated: Bool) {
imagePicker.delegate = nil;
}
#IBAction func back(sender: UIButton) {
delegate?.goodPic(self)
}
#IBAction func coverPick(sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary;
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
//Delegates from UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
if let img = info[UIImagePickerControllerOriginalImage] as? UIImage{
self.imageData = UIImageJPEGRepresentation(img, 1.0)
delegate?.goodPic(self)
dismissViewControllerAnimated(true, completion: nil)
}
}
}
Hope help you!