Hi I'm new in iOS development. I've one main screen with navigation bar hidden true. From there I am navigating to another view using back segue. but when I click back it showing navigation bar on main screen. Here is my problem description.
In main screen onviewload I am doing :
self.navigationController.navigationBarHidden = YES;
once user go to another view using back segue in new controller, I'm doing
self.navigationController.navigationBarHidden = NO;
And now, if I click back it will show navigation bar on main window also which I don't want. Basically I want main screen without navigation bar and next window with navigation bar.
How to do this. Need Help. Thank you.
Put that code in viewWillAppear instead of viewDidLoad, and it should work properly.
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = YES;
}
I have a Tab viewcontroller consist of 4 tabs, one of my tab doesn't need navigationbar, but others need.
None of the previous answers solve my case, these code does.
//隐藏App导航条,使用RN自己的导航条
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.navigationBar.hidden = YES;
// self.navigationController.navigationBarHidden = YES; //这句是 **完全没** 个卵用
// [self.navigationController setNavigationBarHidden:YES animated:NO];
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:NO];
}
//恢复App导航条
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
self.navigationController.navigationBar.hidden = NO;
// self.navigationController.navigationBarHidden = NO; //这句是 **完全没** 个卵用
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
Don't use
self.navigationController.navigationBarHidden = YES;
You should use
self.navigationController.navigationBar.hidden = NO;
For Swift 4, add following in viewWillAppear
self.navigationController?.setNavigationBarHidden(false, animated: false)
self.navigationController?.setNavigationBarHidden(false, animated: false)
Put the above line of code in viewWillAppear instead of viewDidLoad.
In my .plist file, I have "View controller-based status bar appearance" set to NO. But after UIImagePickerController, my app behaves as if the option is set to YES.
In my app, I present a VC that presents a UIImagePickerController.
The problem happens like this:
After photo picker is presented, when a photo library is picked, the color of the status bar text changes.
Then once, UIImagePickerController is dismissed, status bar spacing
changes for the rest of my app and all the navigation bar for other controllers displays under the status bar.
Is there a way to solve this without managing status bar in my view controllers?
None of the solutions above worked for me, but by combining Rich86man's and iOS_DEV_09's answers I've got a consistently working solution:
UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
and
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
Regarding this awesome solution. For 2014 / iOS8 I found in some cases you need to ALSO include prefersStatusBarHidden and, possibly, childViewControllerForStatusBarHidden So...
-(void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
-(BOOL)prefersStatusBarHidden // iOS8 definitely needs this one. checked.
{
return YES;
}
-(UIViewController *)childViewControllerForStatusBarHidden
{
return nil;
}
-(void)showCamera
{
self.cameraController = [[UIImagePickerController alloc] init];
self.cameraController.delegate = (id)self; // dpjanes solution!
etc...
I faced this same issue today. Here is my solution.
In the view controller who calls the image picker, set yourself as the delegate of the image Picker. (You're probably already doing this)
UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
Since UIImagePickerController is a type of Navigation controller, you're also setting yourself as the UINavigationController delegate. Then :
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
Replace UIStatusBarStyleLightContent with whatever style you are looking for.
The accepted answer will work if you have the 'View controller-based status bar appearance' set to NO in your .plist file. If indeed you need to control the status bar in some other view controllers and have this option set to YES, the other way to make UIImagePickerController to behave correctly is by subclassing it
// .h
#interface MYImagePickerController : UIImagePickerController
#end
// .m
#implementation MYImagePickerController
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent; // change this to match your style
}
#end
i faced the same problem.
here is my solution.
put this in the viewWillAppear of the view controller from which you are opening the image pickerview
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
Can you try this. I think needsStatusBarApperanceUpdate will work.
1 -Set UIViewControllerBasedStatusBarAppearance to NO.
2- Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
3- [self setNeedsStatusBarAppearanceUpdate];
I found this to offer proper handling, there's two parts.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
...
the UIImagePickerController itself presents view controllers, so this delegate works for all presenters on the stack.
the viewWillAppear ensures this view controller itself is always reset whenever a presenting view controller dismisses above it.
I had the same problem.
Add in info plist: "View controller-based status bar appearance" with value "NO"
Example here https://stackoverflow.com/a/19211669
This solution works for me.
This is probably a bug. I solved the problem by setting "View controller-based status bar appearance" set to YES and in every view controller pasting in the following code:
- (BOOL)prefersStatusBarHidden
{
return YES;
}
Then my app behaves as expected.
For hiding the status bar in UIImagePicker :
-
(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
and when UIImagePicker is dismissed to hide the status bar in View controller use the following code :
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
try this ....
this will work in both cases i.e whether you use presentModalViewController and pushViewController
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
delegate methods
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[picker dismissViewControllerAnimated:YES completion:^{}];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[picker dismissViewControllerAnimated:YES completion:nil];
}
All the above didn't work for me. I solved the issue by changing the presentation style to:
imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
None of the above solutions worked for me.
I present UIImagePickerController as modal view controller. After dismissing UIImagePickerController the status bar state was:
[UIApplication sharedApplication].statusBarOrientation = 0 (UIDeviceOrientationUnknown)
[UIApplication sharedApplication].statusBarFrame = { 0, 0, 0, 0}
The solution that fixed the problem for me was restoring statusBarOrientation after dismissing UIImagePickerController:
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
[self.viewController presentViewController:cameraUI animated:true completion:^(void){ }];
...
[self.viewController dismissViewControllerAnimated:animated completion:^(void){
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
}];
This code helped me to customize status bar style.
EDIT: this solution works if "View controller-based status bar appearance" == YES
#implementation UIImagePickerController (IOS7_StatusBarStyle)
-(UIViewController*)childViewControllerForStatusBarStyle
{
return nil;
}
-(UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
#end
All the answers above is ok and can help.
I had the same problem having to manage the application runned under different iOS versions.
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
if(IS_IOS8_AND_UP) {
imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
} else {
imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
}
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
Then, in delegate:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
/* Cancel button color */
_imagePicker.navigationBar.tintColor = <custom_color>
/* Status bar color */
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}
Yet another solution which may work in some of the situations.
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .PhotoLibrary
imagePicker.navigationBar.barStyle = .Black
Have you tried calling [self setNeedsStatusBarAppearanceUpdate] when your presenting view controller reappears?
I try to hide the status bar in UIImagePickerController in iOS7, but I still don't know how to do this. I use
- (void)viewWillAppear:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES
withAnimation:UIStatusBarAnimationNone];
}
in the ViewController that call the UIImagePickerController, and set "View controller-based status bar appearance = NO" in the plist file. Hope this can help.
try this :
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
and in the protocol implement, use this:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
This solved it for me...:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[picker dismissViewControllerAnimated:YES completion:nil];
}
Nothing here specifically fixed the problem in that I was having (and perhaps that the OP was having too), so I thought I would share my answer. Instead of hiding the status bar which I think is a buggy solution (I noticed that it would sometimes leave my app in a state where the status bar was hidden when it shouldn't be). I instead opted to try and play nice with the UIStatusBarStyles.
When the UIImagePickerController has its view presented I set the status bar style to default since the default background color is a light grey.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}
Then, when the image picker is dismissed, I set it back to the UIStatusBarStyleLightContent.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//work
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
[self dismissViewControllerAnimated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
//work
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
[self dismissViewControllerAnimated:YES completion:NULL];
}
In this case,We are using 2 steps
In first step:
Add in info.plist: "View controller-based status bar appearance" with value "NO"
In Second step: Use/call this code with delegate of UIImagePickerController
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if([navigationController isKindOfClass:[UIImagePickerController class]])
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
In case of IOS-7 add One more Function
- (BOOL)prefersStatusBarHidden
{
return YES;
}
As of iOS 8.1, it seems like they've finally fixed this bug! I was able to remove all of the workarounds I employed from my code.
Using the default iOS 8 behaviour I was having problems with the status bar appearing when I wanted it hidden.
The solution I found was that, directly after calling presentPopover from my view controller I did:
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate) withObject:nil afterDelay:0.01];
I also had to add this to my main view controller:
- (UIViewController *)childViewControllerForStatusBarHidden
{
return nil;
}
So I had this problem and I was able to solve it by simply implementing a single delegate function. The background of my status bar is black, and so UIStatusBarStyle for my application is .LightContent. When I presented the UIImagePickerController to select a photo from the device storage, the status bar was fine. However, upon clicking into a directory such as "Camera Roll" or "Favorites," effectively pushing onto the navigation stack, the status bar disappeared. Upon selecting a photo, there was no status bar at all; upon dismissing another modal view controller, only the battery was present, indicating the rest of the status bar may be black as well.
I tried some of the other solutions such as extending UIImagePickerController, but in Swift, you cannot override using extensions. I then tried to subclass UIImagePickerController and tried to hide its status bar on viewWillAppear() and unhiding the status bar on viewWillDisappear. I was able to see the status bar hide with a .Slide animation, but since the status bar was invisible upon selecting a directory, I was not able to see the status bar unhide. Again, the green battery came back with the rest of the status bar invisible upon dismissing a modal view controller. I also tried overriding prefersStatusBarHidden(), but that function was never called, so I tried calling setNeedsStatusBarAppearanceUpdate() to ensure that prefersStatusBarHidden() is called by the system, but it still is not called. Also, there is the suggestion to set the status bar to be hidden on the delegate method navigationController willShowViewController. Once again, all this does is hide the status bar, which does not solve the problem. As it turns out, it seems that the status bar style is changed upon pushing onto the navigation stack of the UIImagePickerController. To solve the problem entirely, I did not have to write extensions or subclass UIImagePickerController. All you need to do is set the delegate and set the status bar style to remain the same. This addition made it as if the problem never existed.
let pickerController = UIImagePickerController()
pickerController.delegate = self
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: false)
}
I actually found a better way to set the status bar background color in Image Picker. Basically you need to set the backgroundImage from the navigationBar to nil, because is default in Image Picker has a backgroundImage as a white Image.
Is it possible to pop up an UIViewController (xib file) like UIPopOverControl in iPad ?
I have a separate NIB file which is linked to an UIViewController. I want to popup that NIB file along with the button pressed with a customised size (200,200).
Is this possible?
I am trying to get something like this on the iPhone - http://www.freeimagehosting.net/c219p
You can also use one of these custom made clases to show a popup:
https://github.com/sonsongithub/PopupView
https://github.com/werner77/WEPopover
https://github.com/50pixels/FPPopover
Example with FPPopover:
//the view controller you want to present as popover
YourViewController *controller = [[YourViewController alloc] init];
//our popover
FPPopoverController *popover = [[FPPopoverController alloc] initWithViewController:controller];
//the popover will be presented from the okButton view
[popover presentPopoverFromView:okButton];
//release if you arent using ARC
[controller release];
yes it is. load Your pOpOver controller lazily at the point when it is needed. add its view as a subview (you could animate the addition). make its frame size what You need and add the image You have shown as a background subview of the pOpOver controller along with other controls You want in the pop up.
good luck
UPDATE:
alright, ii will show You how ii do this in my app Lucid Reality Check (deployment target iOS4.3).
one can use a UIPopoverController to present another controllers view. what ii do first is to make sure ii always know the current orientation of the device, so ii can reposition the popup on rotation (maybe this works by itself on iOS6?). so in my base controller (from where ii want to show a popup) ii have an instance variable like this:
UIInterfaceOrientation toOrientation;
and also:
UIPopoverController *popover;
UIButton *popover_from_button;
BOOL representPopover;
popover will be reused for all popups, and popover_from_button will hold the button from which the popup is initiated.
then the next code comes into the base controller:
- (void)popoverWillRotate {
if ([popover isPopoverVisible]) {
[self dismissPopover];
representPopover = YES;
}
}
- (void)popoverDidRotate {
if (popover && representPopover) {
representPopover = NO;
[self representPopover];
}
}
these two methods have to be called every time the device is rotated, like this:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
//DLOG(#"willRotateTo %i", toInterfaceOrientation);
toOrientation = toInterfaceOrientation;
if ([Kriya isPad ]) {
[self popoverWillRotate];
}
}
as one can see, first the orientation is captured then popoverWillRotate is called. this would hide the popover during the orientation animation. and after rotating, the popover must be redisplayed like this:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
//DLOG(#"didRotateFrom %i", fromInterfaceOrientation);
//[self layout:toOrientation]; //do some layout if You need
if ([Kriya isPad]) {
[self popoverDidRotate];
}
}
- (void)layout:(UIInterfaceOrientation)toInterfaceOrientation {
//one can do view layout here, and call other controllers to do their layout too
}
now that the orientation changes are worked out, the code for presenting the popover arrives here:
#pragma mark Popovers
- (void)presentPopoverWith:(id)controller fromButton:(UIButton*)button {
if (popover)
[popover release];
if (popover_from_button)
[popover_from_button release];
popover_from_button = [button retain];
popover = [[UIPopoverController alloc] initWithContentViewController:controller];
[popover setDelegate:self];
[self representPopover];
}
- (void)representPopover{
if (popover) {
UIPopoverArrowDirection arrowDirection = UIPopoverArrowDirectionAny;
UIViewController *vc = (UIViewController*)[popover contentViewController];
CGSize contentSize = [vc contentSizeForViewInPopover];
if (contentSize.width > 0 && contentSize.height > 0) {
[popover setPopoverContentSize:contentSize animated:NO];
}
//DLOG(#"representPopover rect:%#", [Kriya printRect:popover_from_button.frame]);
[popover presentPopoverFromRect:CGRectOffset(popover_from_button.frame, 0, popover_from_button.frame.size.height + 7.0) inView:self.view permittedArrowDirections:arrowDirection animated:YES];
}
}
- (void)dismissPopover {
if (popover) {
[popover dismissPopoverAnimated:YES];
}
}
finally, if one wants to be notified when the popover is dismissed, the base controller must implement a delegate method:
#pragma mark UIPopoverControllerDelegate
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
//do something important here like drink some water
}
and don't forget to make the base controller a UIPopoverControllerDelegate in its header.
a use case for this way of doing popups would then look like this:
- (void)takeImage {
UIImagePickerController *picker = [[[UIImagePickerController alloc] init] autorelease];
[picker setDelegate:self];
[picker setAllowsEditing:NO];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
[picker setSourceType:UIImagePickerControllerSourceTypeCamera];
if ([Kriya isPad]) {
[self presentPopoverWith:picker fromButton:backgroundImageButton];
} else {
//modals on iPhone/iPod
//DLOG(#"takeImage addSubview picker");
[self presentModalViewController:picker animated:YES];
}
} else {
//DLOG(#"no camera");
}
}
this would use an image picker as the content for the popup, but one can use any controller with a valid view. so just do this:
[self presentPopoverWith:popupsContentController fromButton:tappedButton];
one should not have any missing information, :), the method [Kriya isPad] is just this:
+ (BOOL)isPad {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
// iPad capable OS
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
//this is an iPad
return YES;
}else {
//this is an iPod/iPhone
return NO;
}
#else
//can not pissible be iPad
return NO;
#endif
}
ENJOY!
I have a button where when the user presses it, he is navigated to camera to take a pic.
When he takes the pic, he presses done and gets back to the controller. But when that happens the navigation bar gets up in the screen, gets below the battery/signal bar that the telephone has. The weird thing is that this happens on 4/4s but not on 3gs
It is rather tough to answer the question without knowing a bit more details, but here's some code I use to bring up the camera, take the picture, then close the camera successfully. The method can be called by using one line of code: [self takePhoto];
- (void) takePhoto {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
//Clear out the UI first
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
//picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; -> use this if you want them to select from the library
[self presentViewController:picker animated:YES completion:nil];
} else {
//Device does not support a camera, show a message if desired
}
}
Then you need a delegate for it all so the program knows what to do when an image is taken or selected and how to close, that's what this code is:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
self.workingImage = nil;
//I grab the image and store globally, but first I manually scale and rotate it if necessary
self.workingImage = [self scaleAndRotateImage:[info objectForKey:UIImagePickerControllerOriginalImage]];
//I display the image in my UI view, so this chunk of code will size it properly
CGRect bound;
bound.origin = CGPointZero;
bound.size = img.size;
imageView.bounds = bound;
//Set the UI image view and dismiss the controller
[imageView setImage:self.workingImage];
[picker dismissModalViewControllerAnimated:YES];
}
Obviously, make sure your controller .h implements the delegate properly like so:
#interface ViewController : UIViewController<UIImagePickerControllerDelegate> { ... }
Hope this helps?
I have an app that uses the UITabBarController and one of the tabs is supposed to be a full on camera view (similar to Instagram). When I launch the app and go to that view, most of the screen is blank and no image library picker/camera view loads. Any help would be greatly appreciated.
Here is my viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
imagePicker = [[UIImagePickerController alloc] init];
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
} else {
[imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
}
[imagePicker setDelegate:self];
[imagePicker setEditing:NO];
// Place image picker (camera viewing angle on the screen)
[self presentViewController:imagePicker animated:YES completion:nil];
}
Try putting that code in viewDidAppear instead -- that worked for me. Better yet, would be to put all but the last line in viewDidLoad, so it's only called once, and just put the last line in the viewDidAppear method. When you cancel the image picker (the only thing I tested), it will just reappear, since viewDidAppear will be called again, so you need to implement imagePickerControllerDidCancel: like this to keep that from happening:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismissViewControllerAnimated:YES completion:nil];
self.imagePicker = nil;
}
And, in your viewDidAppear, put in an if statement to see if the picker exists before trying to present it:
if (self.imagePicker) {
[self presentViewController:self.imagePicker animated:YES completion:nil];
}