Pick image from custom image library [Swift] - swift

I am new to Swift/app development. I have successfully developed an app that uses an UIImagePickerController to let the user select an image from the device's photo library. However, I would like the user to select images from a custom set of images, and not from the device's photo library.
What would be the easiest way to implement this? Any help appreciated!
Edit
As per requested here is some of the code I am using.
I have a view controller that adheres to the following protocols:
class StockViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate
On my main storyboard, I have an UIImageView with a tap gesturer which triggers an action on selectImageFromPhotoLibrary.
#IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {
// UIImagePickerController is a view controller that lets a user pick media from their photo library.
// Hide the keyboard.
let imagePickerController = UIImagePickerController()
// Only allow photos to be picked, not taken.
imagePickerController.sourceType = .PhotoLibrary
imagePickerController.allowsEditing = false
// Make sure ViewController is notified when the user picks an image.
imagePickerController.delegate = self
presentViewController(imagePickerController, animated: true, completion: nil)
}
The only source types I can select for the imagePickerController are SavedPhotoAlbums, Camera or PhotoLibrary. I cannot select any app image folder.

Related

google placepicker for ios and BackgroundMapViewController.swift

I'm trying to implement google's placepicker for ios.
There is some demo code at:
https://github.com/googlemaps/maps-sdk-for-ios-samples/tree/master/GooglePlacePicker/GooglePlacePickerDemos
And i get most of it except the line in the file PickAPlaceViewController.swift
var mapViewController: BackgroundMapViewController?
In the github repo Google have provided their own class BackgroundMapViewController.
Do I need to create an instance of this class to use the place picker?
Or can I just use a GMSMapView like I ordinarily would with google maps.
Thanks.
For Google Places Controller you just need below code to show or present Places Controller in your App.
Put this in ur Button Action method :
// Create a place picker. Attempt to display it as a popover if we are on a device which
// supports popovers.
let config = GMSPlacePickerConfig(viewport: nil)
let placePicker = GMSPlacePickerViewController(config: config)
placePicker.delegate = self
placePicker.modalPresentationStyle = .popover
placePicker.popoverPresentationController?.sourceView = pickAPlaceButton
placePicker.popoverPresentationController?.sourceRect = pickAPlaceButton.bounds
// Display the place picker. This will call the delegate methods defined below when the user
// has made a selection.
self.present(placePicker, animated: true, completion: nil)
Hope This will helps to show Place Picker in your app.

UIBarButtonItem not triggering IBAction

I'm trying to create a UIBarButtonItem that opens the camera once the button has been tapped. For some reason, my takePicture(_sender:) function doesn't seem to be getting called.
I originally tried to create my UIBarButtonItem using the Interface Builder. Here was the interface and a screenshot of the actions connected to the UIBarButtonItem:
And here is the code for my takePicture(_sender:) function:
#IBAction func takePicture(_ sender: UIBarButtonItem) {
print("Taking picture...")
let imagePicker = UIImagePickerController()
// If the device has a camera, take a picture; otherwise,
// just pick from photo library
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
} else {
imagePicker.sourceType = .photoLibrary
}
imagePicker.delegate = self
// Place image picker on the screen
present(imagePicker, animated: true, completion: nil)
}
The little circle next to my function declaration is filled in and connected properly:
However, when I load the simulator and press the button, the UIImagePickerController never appears and my print() function is never called in the code.
So, I then tried to declare the UIBarButtonItem programmatically to see if perhaps it was an issue under-the-hood of Xcode's Interface Builder. Here was my code:
(Note: I deleted the UIBarButtonItem from the Interface Builder and then I connected the UIToolbar to my code using an #IBOutlet.)
override func viewDidLoad() {
super.viewDidLoad()
let takePictureBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.camera, target: self, action: #selector(DetailViewController.takePicture))
toolBar.setItems([takePictureBarButton], animated: false)
}
#objc func takePicture() {
print("Taking picture...")
let imagePicker = UIImagePickerController()
// If the device has a camera, take a picture; otherwise,
// just pick from photo library
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
} else {
imagePicker.sourceType = .photoLibrary
}
imagePicker.delegate = self
// Place image picker on the screen
present(imagePicker, animated: true, completion: nil)
}
As a last ditch attempt at debugging this program and trying to find where the problem lies, I created a temporary button in my UI and connected that to my takePicture(_sender:) function instead (I changed the signature from a UIBarButtonItem to a UIButton). That worked perfectly. This tells me that the problem is not with the function itself, but has something to do with the connection.
I was seconds away from posting this question when I found a similar question. The user stated that the root of their problem lied in a UITapGestureRecognizer on their View Controller.
To solve my problem, I simply set my UITapGestureRecognizer's target to be my StackView instead of the the entire view.
Original:
Resolved:
I'd be curious to learn why the UITapGestureRecognizer stopped my UIBarButtonItem from being tapped, but not the normal UIButton. Seems a little strange...
Swift 4
I went through this problem and referenced above answers. The project I worked on had UIButton as navigation bar item and hence it comes under navigation item and I found out that the outlet for the IBAction should be connected to the button in the bar button item rather than connecting it to the bar button item itself. In mattkx4's question, the IBAction has 'UIBarButtonItem' as its sender. I fixed the issue by connecting the button inside the bar button item to the action.
As you can see there is a button inside the bar button item. Connect the action to this button and the action will be triggered.
make sure you connect your camera button with action for touchUpInside event

How does presentViewController display the view?

I'm curious as to what the presentViewController does with the first parameter, imagePickerController. Given the way I assigned imagePickerController's properties, will the presentViewController use all that information to display the view?
#IBAction func imageFromPhotoLibrary(sender: UITapGestureRecognizer) {
// Hide the keyboard.
myTextField.resignFirstResponder()
// UIImagePickerController is a view controller that lets a user pick media from their photo library.
let imagePickerController = UIImagePickerController()
// Only allow photos to be picked, not taken.
imagePickerController.sourceType = .PhotoLibrary
// Make sure ViewController is notified when the user picks an image.
imagePickerController.delegate = self
presentViewController(imagePickerController, animated: true, completion: nil)
}
presentViewController won't use any of the options. The imagePickerController you passed in will use those options.
Since the Apple APIs are pretty well designed, presentViewController does one thing (SRP), and does exactly what it says it does... presents the view controller you pass it.
The imagePickerController is in charge controlling the view of the image picker.

How do you display an Uploaded (From Camera Roll) Image in Swift

So I have just created my first app! It is almost finished! The only problem, I need to get a picture (uploaded from camera roll) into a Ui-Image! Please Help!
Also, I don't want to upload it to PHP or any other database languages. Just want it to stay.
You will need to export your Camera Roll image from iPhoto in a standard format, such as png. Here's an instruction page for exporting your photo.
Once you have your image in the correct format you can add it to your app's assets. In your Xcode Project Navigator, appears on left when not collapsed (look for a little folder icon), find Assets under your project file. Click on Assets, a new menu will fly out with a '+' at the bottom to add a group or image set. Follow the prompts to add your image.
Now that you can access the image from your application you may set it as the source file for a UIImage. Click on the image in your Storyboard. The Image attribute should now show your new photo in the drop down as an option. Select it. Alternatively, you may set the image attribute in your code. Something like this in Swift:
let myImage = UIImage(named: "yourImageName")!
imageView.image = myImage
Follow up to your comment about you image source. You can add a button that opens the user's album or camera. The higher level logic for onButtonClick looks something like this:
#IBAction func onButtonClick(sender: AnyObject) {
let actionSheet = UIAlertController(title: "Change Photo", message: nil, preferredStyle: .ActionSheet)
actionSheet.addAction(UIAlertAction(title: "Album", style: .Default, handler: {action in self.showAlbum()}))
self.presentViewController(actionSheet, animated: true, completion: nil)
}
func showAlbum() {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .Camera
presentViewController(picker, animated:true, completion:nil)
}
Here are details for the UIImagePickerController()-- You will need a UIImagePickerControllerDelegate to finally set the image.

How do i get rid of xib after presenting it?

I am creating my own UIImagePicker Overlay and am using a Xib in order to display the overlay. Whenever I present the imagepicker, it seems to present twice, once when I call the main bundle to load the nib and the other when I explicitly present the imagepickercontroller. The main problem i'm having is when I dismiss the imagepickercontroller, the first one goes, which is great, but the underlying view of the xib still remains and doesn't go regardless of what i do.
I tried to convert the Objective-C example project for how to create a custom uiimagepickercontroller Apple has on their website into Swift. I'm not sure what I"m doing wrong, here is my code:
func showImagePickerForSourceType(sourceType: UIImagePickerControllerSourceType) {
let picker = UIImagePickerController()
picker.modalPresentationStyle = UIModalPresentationStyle.CurrentContext
picker.sourceType = sourceType
picker.delegate = self
if sourceType == UIImagePickerControllerSourceType.Camera {
//gets rid of the out of the box imagepicker
picker.showsCameraControls = false
//loads the overlay xib for the camera
NSBundle.mainBundle().loadNibNamed("OverlayView", owner: self, options: nil)
self.overlayView.frame = (picker.cameraOverlayView?.frame)!
picker.cameraOverlayView = self.overlayView
self.overlayView = nil
//makes the image capture screen the full screen size
let screenSize: CGSize = UIScreen.mainScreen().bounds.size
let cameraAspectRatio: Float = 4.0 / 3.0
let imageWidth:Float = floorf(Float(screenSize.width) * cameraAspectRatio)
let scale: Float = ceilf((Float(screenSize.height + 120) / imageWidth) * 10.0) / 10.0
picker.cameraViewTransform = CGAffineTransformMakeScale(CGFloat(scale), CGFloat(scale))
}
self.imagePickerController = picker
self.presentViewController(self.imagePickerController, animated: true, completion: nil)
}
Here is the code for a button on the xib dismissing the view. How can i fix this? Because i'm printing out the array of view controllers on the navigation stack, and it only shows one.
#IBAction func goBack(sender: AnyObject) {
self.imagePickerController.dismissViewControllerAnimated(true, completion: nil)
}
It sounds like you have your view controller's view outlet connected to the view in your .xib file in addition to the overlayView outlet. This would probably cause what you're describing.