In UIImagePickerController Cancel button not showing? - ios

here i m using below code. please help me if anybody know this issue.
and i tried below urls also, but its not working. please help me
iOS7 UIImagePickerController cancel button disappear
UIImagePickerController inside UIPopoverController doesn't show Cancel button on iOS7
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:NULL];
picker.navigationBar.tintColor = [UIColor redColor];
picker.navigationBar.barStyle = UIBarStyleBlackOpaque;
picker.navigationBar.topItem.rightBarButtonItem.tintColor = [UIColor blackColor];
My Issue:
My Req:

This is what worked for me:
present(imagePicker, animated: true, completion: {
imagePicker.navigationBar.topItem?.rightBarButtonItem?.tintColor = .black
})

Looks like apple made some mistake with it (iOS 10, Xcode 8) because just changing tint color of UIImagePickerController could not be done, cause, before controller isn't have topItem property, or navigationController property. So have done the changes in UIImagePickerController extension. But I checked navigationController and topItem in those overrided methods: viewDidLoad, viewWillAppear, viewDidAppear. but it still was nil. So i decide to check it in viewWillLayoutSubviews, and voila! It's wasn't nil, so we can set bar tint color of exact rightBarButtomItem here!
Here is example:
extension UIImagePickerController {
open override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.navigationBar.topItem?.rightBarButtonItem?.tintColor = UIColor.black
self.navigationBar.topItem?.rightBarButtonItem?.isEnabled = true
}
}
And don't forget to call super.viewWillLayoutSubviews, it's very important ;-)
EDIT: But it still has problems when return to the albums screen..

If every effort doesn't work then you must have to use appearance() method. So try to write following lines in any view controller(UIImagePickerController) which you want to present. You can use appearance in any class but you may have used UIBarButtonItem.appearance() for some other purposes so find that and write that code in viewDidDisappear().
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .normal)
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .highlighted)

Swift 4.2 Solution, Add below code into AppDelegate's didFinishLaunchingWithOptions
UINavigationBar.appearance(whenContainedInInstancesOf: [UIImagePickerController.self]).tintColor = .black

I used the same code that you posted. Its showing the "cancel" button.
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:NULL];
picker.navigationBar.tintColor = [UIColor redColor];
picker.navigationBar.barStyle = UIBarStyleBlackOpaque;
picker.navigationBar.topItem.rightBarButtonItem.tintColor = [UIColor blackColor];
[self presentViewController:picker animated:YES completion:NULL];
May be you are using any custom navigation bar and you set the property for app delegate to changing the tint color of navigation nar.

I think you have not embedded viewController to Navigation Controller
Please do that and try the code: (Objective - c)
-(void)viewDidLoad
{
[super viewDidLoad];
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
[picker dismissViewControllerAnimated:YES completion:^{
}];
UIImageView *imageview=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 300)];
imageview.image=image;
}

Seems like update some of item properties make the button visible, so... just turn it enabled like that:
present(imagePicker, animated: true, completion: {
self.imagePicker.navigationBar.topItem?.rightBarButtonItem?.isEnabled = true
})

If any of the above does not work out for you,
try adding this when you define your UIImagePickerController
imagePicker.modalPresentationStyle = .popover // Or.fullScreen (Can also check cases for iPad and iPhone as per requirement)
Worked for me like a charm. Was quite bugged up by this

Subclass UIPickerViewController as below:
class CustomImagePicker: UIImagePickerController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
UINavigationBar.appearance().tintColor = UIColor.black
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.init(red: 0.0, green: 122.0/255.0, blue: 1.0, alpha: 1.0)], for: .normal)
}
override func viewWillDisappear(_ animated: Bool) {
UINavigationBar.appearance().tintColor = UIColor.white // your color
UIBarButtonItem.appearance().setTitleTextAttributes(nil, for: .normal)
super.viewWillDisappear(animated)
}
}
And use As:
func openGallary()
{
picker!.sourceType = UIImagePickerController.SourceType.photoLibrary
picker!.modalPresentationStyle = .currentContext
self.present(picker!, animated: true, completion: nil)
}

change the UIImagePickerController navigationBar.tintColor
try this code :
UINavigationBar *bar = [self.navigationController navigationBar];
[bar setTintColor:[UIColor blueColor]];

UIImagePickerController *imgPicker=[[UIImagePickerController alloc]init];
imgPicker.delegate = self;
imgPicker.navigationBar.barStyle = UIBarStyleBlackOpaque;
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imgPicker.allowsEditing = NO;
if([UIImagePickerController isSourceTypeAvailable: sourceType])
{
imgPicker.sourceType=sourceType;
[self presentViewController:imgPicker animated:YES completion:NULL];
}

This worked for me:
let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([NSForegroundColorAttributeName: .blue), NSFontAttributeName: UIFont.boldSystemFont(ofSize: 16.0)], for: .normal)

I have face this kind of same issue and after wasting lot of time i found solution. I have customise navigation bar appearance like below code that why this issue was happened.
UINavigationBar.appearance().backIndicatorImage = UIImage(named: "ic_left")
let attributes = [NSAttributedString.Key.font: UIFont(name: "FuturaPT-Medium", size: 16)!]
UINavigationBar.appearance().titleTextAttributes = attributes
UINavigationBar.appearance().setBackgroundImage(UIImage(named: "line.png"),for: .bottom,barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage(named: "line.png")
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor:
UIColor.clear], for: .normal)
This is just custom appearance of navigation bar we just need to change last line of code because i have set title color to clear. This is really very simple. Put this code before presenting your image picker controller.
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor:
UIColor.black], for: .normal)
And again if you don't want navigation bar button title make text color to clear.
Thanks

Please try this code for swift 3 or above
let picker = UIImagePickerController()
picker.navigationBar.topItem?.rightBarButtonItem?.tintColor = UIColor.white

Swift 5:
imagePicker.modalPresentationStyle = .fullScreen

Try this Code:
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
And add delegate Method: - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
[picker dismissViewControllerAnimated:YES completion:^{
}];
self.img = image;
[self.iconBtn setBackgroundImage:image forState:UIControlStateNormal];
}

i think this will help you.Just paste the code inside imagePickerControllerDidCancel then dismiss it (Swift 4).
picker.setNavigationBarHidden(false, animated: true)

Related

Is is possible to change title of `UIImagePickerController`when choosing videos?

I have open photo gallery for choosing video. Here is my code :


- (void)selectMediaFrom:(UIImagePickerControllerSourceType)sourceType {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = sourceType;
imagePicker.delegate = self;
//imagePicker.allowsEditing = YES;
if (selectedMediaType == MediaVideos) {
imagePicker.mediaTypes = #[(NSString *)kUTTypeMovie, (NSString *)kUTTypeVideo];
if (sourceType == UIImagePickerControllerSourceTypeCamera) {
imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
}
}
else if (selectedMediaType == MediaPhotos) {
imagePicker.mediaTypes = #[(NSString *)kUTTypeImage];
if (sourceType == UIImagePickerControllerSourceTypeCamera) {
imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
}
}
if (IS_IPHONE) {
[self presentViewController:imagePicker animated:TRUE completion:nil];
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
[self setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:imagePicker animated:TRUE completion:nil];
});
}
}


And it is always showing title of UIImagePickerController as Photos, See screenshot I have attached.
But, I have open iPhone default Photos app and check, that shows videos folder : See below
Then why it is not showing Videos title ? Can we change it ?
Yes You can change the title of Navigation which you want.
Add the delegate of UINavigationControllerDelegate
Swift 3.0
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool){
viewController.navigationItem.title = "Kirit Modi"
}
Objective C
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
[viewController.navigationItem setTitle:#"Kirit Modi"];
}
See Output :
Thanks for this. I was able to adapt for my situation. Because I present my ImagePicker programmatically from another VC, I had to use similar code.
I first created a variable for the presenting VC:
let imagePickerController = UIImagePickerController()
And then later in the presenting VC, I used:
Swift 4
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
// change title here to something other than default "Photo"
imagePickerController.navigationBar.topItem?.title = "choose photo"
}
It works well. Hope this helps someone.

Making an Image Picker with UIButton in Swift

I would like to make an Image Picker with an UIButton pointing to the ImagePickerView but i don't know how to proceed.
We'll say that i want to connect the ViewController "A" (with the UIButton) to the ViewController "B" (UIImagePicker).
This is what i tried : I have a storyboard with multiples ViewController, and i don't know why i can't make an IBAction from the ViewController "A" to the ViewController "B".
Should i make the ImagePickerView programatically only or can i use Storyboard?
Thanks in advance !
Answering myself, this is how i did in swift and it works (to help other people)
var currentImage: UIImage!
#IBAction func ImagePicker(sender: UIButton)
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary)
{
let picker = UIImagePickerController()
picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
picker.delegate = self
picker.allowsEditing = true
self.presentViewController(picker, animated: true, completion: nil)
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
var newImage: UIImage
if let possibleImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
newImage = possibleImage
} else if let possibleImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
newImage = possibleImage
} else {
return
}
dismissViewControllerAnimated(true, completion: nil)
currentImage = newImage
}
UIImagePickerController can't be added in storyboard, so you must do that programmatically. First, create an IBAction with your UIButton:
- (IBAction)openImagePicker:(id)sender;
Your class need to adopt UIImagePickerControllerDelegate and UINavigationControllerDelegate protocol:
#interface MyViewController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
then show image picker in openImagePicker: method:
// Check if image source is available
// In this case, photo library is always available. If you use
// UIImagePickerControllerSourceTypeCamera instead, simulator doesn't have it
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init]; // Create an image picker
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; // Choose source type
picker.delegate = self; // Delegate when image is picked
picker.allowsEditing = YES; // Allow user to edit image before choose it
[self presentViewController:picker animated:YES completion:nil]; // Show image picker
}
To use the picked image, you must implement this method of UIImagePickerControllerDelegate:
/**
* #param picker The image picker
* #param info Dictionary contains picked images and metadata...
*/
- (void)imagePickerController:(nonnull UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(nonnull NSDictionary *)info {
// Because we allow user to edit image,
// so we choose UIImagePickerControllerEditedImage
// You can see other keys in UIImagePickerController class header
UIImage *editedImage = [info objectForKey:UIImagePickerControllerEditedImage];
// Dismiss the picker
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:nil];
});
// Use the image here
}

select a photo from library and open it in another view

i have 2 views. First view contain two buttons: Camera and Library. When i select Library i access the camera roll. I wanna select a photo and open it in another view. Until now i write this functions:
- (IBAction)chooseExistingPhoto :(id)sender{
NSLog(#"chooseExistingPhoto");
pickerLibrary = [[UIImagePickerController alloc] init];
pickerLibrary.delegate = self;
[pickerLibrary setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:pickerLibrary animated:YES completion:NULL];
NSLog(#"chooseExistingPhoto END");
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSLog(#"imagePickerController");
imagePreview.hidden = YES;
captureImage.hidden = NO;
image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
//[captureImage setImage:image];
//ImageLibViewController *svc = [[ImageLibViewController alloc] initWithNibName:#"ImageLibViewController" bundle:nil];
//svc.imageLibModified.image = image;
[self dismissViewControllerAnimated:NO completion:^(void){
UIStoryboard * storyboardd = self.storyboard;
NSString * storyboardName = [storyboardd valueForKey:#"name"];
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
ImageLibViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"imageLib"];
vc.imageLibModified.image = image;
[self presentViewController:vc animated:YES completion:nil];
//[picker showViewController:vc sender:vc];
}];
witch open my image in the same view. How could I open this image in another view?
and my second question is where i put my session in viewdidload or viewdidappear ?
Put this code to the view controller where you want to display camera roll
//This will listen the notification from the other view controller
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(openGallery) name:#"openGallery:" object:nil];
-(void)openGallery
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:NULL];
NSLog(#"open gallery");
}
//This as button click action, when you click the button it will notify the other view, another view has listeners and it will perform the specified method
- (IBAction)chooseExistingPhoto :(id)sender
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"openGallery:" object:nil userInfo:nil];
}
Write the delegate methods and protocols confirmation and everything in the view controller where you going to display the camera roll. Just put the notifier in button action.
This will work I have done this
swift 3
To open camera
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.camera;
imagePicker.allowsEditing = false
imagePicker.cameraDevice = UIImagePickerControllerCameraDevice.front;
self.present(imagePicker, animated: true, completion: nil)
}
To open Library
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary;
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
Delegate methods
private func imagePickerController(picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [String : AnyObject]) {
_ = info[UIImagePickerControllerOriginalImage] as! UIImage //get the image from info
dismiss(animated:true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true,completion: nil)
}
Note : here in code imagePicker.allowsEditing = false
if you choose allowsEditing = true then you need to change UIImagePickerControllerEditedImage instead of UIImagePickerControllerOriginalImage

Restore navigationBar background image after setting it to [UIImage new]

I needed a completely transparent navigation bar for the mapView so I did this:
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[UIImage new]];
That returns the desired effect, as seen here:
Now I have a problem when I go to any other because my navigationBar remains transparent:
How do I restore default settings of the navigationBar's backgroundImage and shadowImage?
Set nil for image of navigation Controller on viewWillDisappear on map view
Set this two method in your mapview
MapView.m
-(void)viewWillAppear:(BOOL)animated{
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[UIImage new]];
}
-(void)viewWillDisappear:(BOOL)animated{
[self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:nil];
}
For Swift 3:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = nil
}
by the way, you get get the original background image by using function
UIImageView *imageView = [self.navigationController.navigationBar
backgroundImageForBarMetrics:UIBarMetricsDefault];
and store the image somewhere, then you use
[self.navigationController.navigationBar setBackgroundImage:imageView
forBarMetrics:UIBarMetricsDefault];
to set it back,but most time, set to nil will solve your problem.

Is it possible to show a UIImagePickerController at full screen in iPad?

I'm currently working on the iPad version of an app, where I used UIImagePickerController to let the user pick a photo from their library.
In the iPad an error message suggests using a popover, but I can't show my imagepicker at fullscreen. Is it possible?
I'm being told that it can be done using presentModalViewController. If so can anyone point me to a tutorial?
It is possible!
Just remove this:
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:picker];
[popoverController presentPopoverFromRect:frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
And use this instead:
[self presentModalViewController:picker animated:YES];
Where picker is your UIImagePickerController.
Not possible. Only Popovers can be used to do it, full screen is not possible.
Swift: It is possible by changing modalPresentationStyle.
#IBAction func openPhotoLibrary(_sender:UIButton){
if !UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){return}
let imagePicker = UIImagePickerController()
imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
imagePicker.allowsEditing = false
imagePicker.delegate = self
imagePicker.modalPresentationStyle = .overCurrentContext
self.present(imagePicker, animated: true, completion: nil)
}

Resources