Is it possible to show a UIImagePickerController at full screen in iPad? - 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)
}

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.

UIImagePickerController slow on opening for the first time, except for when you double tap

I'm getting this really weird behaviour on iOS 9 with swift where I have a tableViewCell that opens an imagePicker when tapped on to take a picture of something, when you tap the cell for the first time it takes like 10 seconds to open the picker, but when you tap it twice it immediately opens...
The initialisation code for the picker is as follows
let certificateImagePicker = UIImagePickerController()
certificateImagePicker.delegate = self
certificateImagePicker.allowsEditing = false
certificateImagePicker.sourceType = .Camera
certificateImagePicker.modalPresentationStyle = .CurrentContext
The code for presenting the picker is presentViewController(certificateImagePicker, animated: false, completion: nil)
I do not now if it related but after opening the picker it show this error message
Snapshotting a view that has not been rendered results in an empty snapshot.
Ensure your view has been rendered at least once before snapshotting or
snapshot after screen updates.
I experienced a similar delay in presenting a UIImagePickerController on the first try. What helped a lot in my case was initialising it when also initializing the parent UIViewController, like so:
class ExampleViewController: UIViewController, UIImagePickerControllerDelegate {
let imagePicker = UIImagePickerController()
func presentImagePicker() {
imagePicker.delegate = self
imagePicker.allowsEditing = false
imagePicker.sourceType = .camera
imagePicker.modalPresentationStyle = .currentContext
self.present(imagePicker, animated: false, completion: nil)
}
}
This is only for debug builds, when you run an app connected to Xcode.
private var imagePickerController = UIImagePickerController()
...
#objc func addPhoto() {
imagePickerController.delegate = self
imagePickerController.sourceType = .savedPhotosAlbum
present(imagePickerController, animated: true)
}
...
When I have this implementation it was waiting when the first present was attempted then after changed my variable to lazy variable, then it worked like charm.
private lazy var imagePickerController = UIImagePickerController()

Wrong popup transition when UIImagePickerController is being presented in a UIPopoverPresentationController on iPad

I was trying to present a UIImagePickerController with source type .PhotoLibrary on iPad. Following Apple's recommendation, it's presented in a popover by using UIPopoverPresentationController.
Here is the actual method for presenting the image picker:
func openImagePicker(with sourceType: UIImagePickerControllerSourceType, from button: UIButton) {
guard UIImagePickerController.isSourceTypeAvailable(sourceType) else {
return
}
guard let mediaTypes = UIImagePickerController.availableMediaTypesForSourceType(sourceType) else {
return
}
let picker = UIImagePickerController()
picker.sourceType = sourceType
picker.mediaTypes = mediaTypes
picker.delegate = self
picker.modalPresentationStyle = .Popover
presentViewController(picker, animated: true, completion: nil)
if let popover = picker.popoverPresentationController {
popover.sourceView = button
popover.sourceRect = button.bounds
}
}
The issue I noticed, particularly on iPad in landscape mode, is that when I went into an album and tapped Back button to go back, the popup transition animation looks like the view is flying off the screen, which is totally weird.
It only happens on landscape. No issue on portrait mode.
I tried searching for similar issues but couldn't find any. Does anyone encounter the same problem, and how did you fix it?

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

In UIImagePickerController Cancel button not showing?

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)

Resources