I am very new to iOS development and Swift, so sorry if this is a trivial question. I have the following code
import UIKit
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var imagePicker: UIImagePickerController!
#IBOutlet weak var imageView: UIImageView!
#IBAction func openGalery(_ sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary;
imagePicker.allowsEditing = true
present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
imagePicker.dismiss(animated: true, completion: nil)
imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In the code I create the func imagePickerController. imagePickerController is responsible for setting the selected image in the imageView. It works. I open the galery, I select an image and there is a transition back to the view with the image set. However, why is it working? I never call the function imagePickerController. Comparing this with the languages I worked before, I should call this function on tap of the select button in the PhotoLibrary. Like an event or something. But here it is somehow called automatically, only by defining the function. Why is that?
imagePicker.delegate = self
Translates to: "Hey imagePicker, when something happens, let me know by calling my UIImagePickerControllerDelegate methods!"
In particular, your implementation of imagePickerController(_:didFinishPickingMediaWithInfo:) is being called, which is part of the UIImagePickerControllerDelegate protocol.
It's delegation pattern.
When you set imagePicker's delegate to self, you're starting receiving events from picker.
Events defined in protocol. In this case it's UIImagePickerControllerDelegate
This pattern frequently using in iOS developing.
More about delegation pattern you can read in Apple's documentation
Related
i want import image in ios from library but i have error
value of type 'viewcontroller' has no member 'present'
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func Alert(sender: AnyObject) {
let nextController = UIImagePickerController()
self.present(nextController, animated: true, completion: nil)
}}
Here's my stripped working code. I use two pickers - one for camera, one for library - because of some odd iOS bug with tint color. To avoid "massive view controller" issues, I tend to move everything possible related to a a UIImagePickerController into a separate file and extension.
class OpenViewController: UIViewController {
let pickerLibrary = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
pickerLibrary.delegate = self
}
}
extension OpenViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#objc func showImagePicker() {
pickerLibrary.allowsEditing = false
pickerLibrary.sourceType = .photoLibrary
present(pickerLibrary,
animated: true,
completion: nil)
pickerLibrary.popoverPresentationController?.sourceView = self.view
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: false, completion: nil)
}
}
While the present code looks correct, I notice several things you didn't post in your code. Maybe because you just didn't post it, but I would definitely check these things:
Are you setting ViewController to be a delegate?
Are you setting ViewController.view to be the source view? This may not be needed for iPhone, but definite helps with iPad.
Have you includes everything needed to be working for UIImagePickerControllerDelegate, UINavigationControllerDelegate?
Now as your error suggests, something else is likely the issue - a UIViewController can present another view controller. In this case you've given us no way to duplicate that error. In other words, I'm assuming that (1) You are seeing a UIButton attached to Alert() - BTW, Swift conventions use lower case for that - and (2) You've proven that when that button is tapped, `Alert() is actually executed.
I am able to start the UIImagePickerController to make a picture:
func selectCamera(){
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.Camera;
imagePicker.allowsEditing = true
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
and with this function to choose from the saved pictures:
func selectPicture() {
let picker = UIImagePickerController()
picker.allowsEditing = true
picker.delegate = self
presentViewController(picker, animated: true, completion: nil)
}
I can either choose a image from my image gallery on the phone or take a picture.
But i want to choose one of the saved image gallery pics inside the camera view, how it is in the standard camera application. Is this possible?
If you want to have Gallery Pics inside camera view, you got to create a custom cameraOverlay view, which has a button to then open the saved pictures.
To make it faster, you can use a library like --> https://github.com/GabrielAlva/Cool-iOS-Camera
Or
You can also have a action sheet, asking user to select which option he wants.
Check this -> How to allow the user to pick a photo from his camera roll or photo library?
& this --> https://github.com/chroman/CRMediaPickerController
I am using this solution, without additional libraries.
First of all don't forget to delegate, UIImagePickerControllerDelegate, and navigation delegate. Those thigns needed only for imagePickerController.
Update, check function saveImageViewToAlbum, be sure that your imageView containt image, otherwise you probably will catch exception. Adds a photo to the saved photos album. The optional completionSelector should have the form:
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
Just created this project, and everything works on swift, iOS 9.3
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var choosenImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func openAlbum(sender: UIButton) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self .presentViewController(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
choosenImageView.image = image
self .dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func saveImageViewToAlbum(sender: UIButton) {
UIImageWriteToSavedPhotosAlbum(choosenImageView.image!, nil, nil, nil)
}
}
So I have a button in the initial control view which takes the user to the camera interface. The user goes back to the initial view controller after taking a photo but how do I make the app close the camera and return to the initial page or a different page after a certain time period if the user doesn't take a picture.
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var CameraButton: UIButton!
#IBOutlet weak var photoLibrary: UIButton!
#IBOutlet weak var imageView: UIImageView!
#IBAction func cameraAction(sender: UIButton) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .Camera
presentViewController(picker, animated: true, completion: nil)
}
#IBAction func photoLibraryAction(sender: AnyObject) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .PhotoLibrary
presentViewController(picker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
imageView.image = info [UIImagePickerControllerOriginalImage] as? UIImage;
dismissViewControllerAnimated(true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Create a NSTimer that gets started when you present the image picker. Set your desired waiting time.
Then, in timer fire method dismiss the image picker.
If user dismisses the image picker before the timer fires, invalidate the timer in didFinishPickingMediaWithInfo
A small warning: I'm a complete noob at swift
Im creating a small app that (will eventually) allow a user to draw over an image they choose from their camera roll on their iPhone. However, im having some trouble getting the image to be set as the background to the UIView (drawView). Could someone give me some pointers as to how I could go about this? The code I have scraped together is shown below.
My ViewController File:
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var drawView : AnyObject!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
imagePicker.delegate = self
#IBAction func clearTapped() {
var theDrawView: DrawView = drawView as! DrawView
theDrawView.lines = []
theDrawView.setNeedsDisplay()
}
let imagePicker = UIImagePickerController()
#IBAction func importImage(sender: AnyObject) {
imagePicker.sourceType = UIImagePickerControllerSourceType.SavedPhotosAlbum
imagePicker.allowsEditing = true
self.presentViewController(imagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]){
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
drawView.backgroundImage = pickedImage
}
func dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
}
}
Also, my drawView has a separate swift file that deals with how the lines are drawn in it by the user.
you're going to want to separate your code a little more. right now, it seems like you're trying to create a controller within a controller. implement a class that is a subclass of UIIMagePickerController with the necessary delegate (you already have the code, so just copy and paste):
class MyImagePicker: UIImagePickerController, UIImagePickerControllerDelegate {
}
then in your view controller, initialize your image picker:
let myImagePicker = MyImagePicker()
call the correct method to return the image, set the background image of your UIView to that image, and then add that view as a subview:
drawView.backgroundImage = pickedImage
self.addSubview(pickedImage)
hope that works!
I useELCImagePickerController to select multiple photos. However when i select photos and click Done button its goes back to select an album page. Please help me so when i select photos it should back to viewController .
Here is code i using:
var picker = ELCImagePickerController(imagePicker: ())
#IBAction func ButtonIsclick(sender: AnyObject) {
picker.delegate = self
self.presentViewController(picker, animated: true, completion: nil)
}
func elcImagePickerController(picker: ELCImagePickerController!, didFinishPickingMediaWithInfo info:[AnyObject]!) {
self.dismissViewControllerAnimated(true, completion: nil)
}
func elcImagePickerControllerDidCancel(picker: ELCImagePickerController!){
self.dismissViewControllerAnimated(true, completion: nil)
}
EDIT: When i debug the code its never call the didFinishPickingMediaWithInfo function
Actually i face this problem because of wrongly set the delegate.
In my question i set delegate as
picker.delegate = self
Which is wrong . Right way is to set ELCImagepickerDelegate is
picker.imagePickerDelegate = self
I solved it - find below the complete final working code -
The problem was I had to add ELCimagepickerdelegate to the class to be as:
class ViewController: UIViewController, UINavigationControllerDelegate, ELCImagePickerControllerDelegate {
however I used to get an error (Type viewcontroller does not conform to protocol) every time I do this, so the solution was to ignore this error until I add the 2 delegate methods below in my code (that stopped the error, which was very confusing - sorry I am new to swift. thanks to everybody tried to help
Whole working Code:
import UIKit
import ELCImagePickerController
class ViewController: UIViewController, UINavigationControllerDelegate, ELCImagePickerControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var picker = ELCImagePickerController()
#IBAction func OpenPhotos(_ sender: AnyObject) {
picker.imagePickerDelegate = self
self.present(picker, animated: true, completion: nil)
}
func elcImagePickerController(_ picker: ELCImagePickerController!, didFinishPickingMediaWithInfo info: [Any]!) {
dismiss(animated: true, completion: nil)
}
func elcImagePickerControllerDidCancel(_ picker: ELCImagePickerController!) {
dismiss(animated: true, completion: nil)
}
}