138

在我的 .plist 文件中,我将“基于控制器的状态栏外观”设置为NO. 但之后UIImagePickerController,我的应用程序的行为就好像该选项设置为YES.

在我的应用程序中,我展示了一个 VC,它展示了一个UIImagePickerController.

问题是这样发生的:

  • After photo picker is presented, when a photo library is picked, the color of the status bar text changes.
  • 然后,一旦UIImagePickerController被解雇,我的应用程序其余部分的状态栏间距会发生变化,其他控制器的所有导航栏都会显示在状态栏下方。

有没有办法在我的视图控制器中不管理状态栏来解决这个问题?

4

25 回答 25

193

上述解决方案都不适合我,但通过结合 Rich86man 和 iOS_DEV_09 的答案,我得到了一个始终如一的工作解决方案:

UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}

关于这个很棒的解决方案。对于 2014 / iOS8,我发现在某些情况下您还需要包括prefersStatusBarHidden,并且可能,childViewControllerForStatusBarHidden所以...

-(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...
于 2013-09-23T13:19:38.137 回答
84

我今天遇到了同样的问题。这是我的解决方案。

在调用图像选取器的视图控制器中,将自己设置为图像选取器的代表。(你可能已经这样做了)

UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;

由于 UIImagePickerController 是一种导航控制器,因此您还将自己设置为 UINavigationController 委托。然后 :

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

将 UIStatusBarStyleLightContent 替换为您正在寻找的任何样式。

于 2013-09-18T22:47:09.577 回答
10

如果您在 .plist 文件中将“基于控制器的状态栏外观”设置为 NO,则接受的答案将起作用。如果您确实需要控制其他视图控制器中的状态栏并将此选项设置为 YES,则使 UIImagePickerController 正常运行的另一种方法是对其进行子类化

// .h
@interface MYImagePickerController : UIImagePickerController
@end

// .m
@implementation MYImagePickerController
- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent; // change this to match your style
}
@end
于 2014-04-22T16:41:50.547 回答
6

我面临同样的问题。

这是我的解决方案。把它放在你打开图像选择器视图的视图控制器的 viewWillAppear 中

-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];

[[UIApplication sharedApplication] setStatusBarHidden:YES];

}
于 2013-09-20T08:08:20.367 回答
4

我发现这可以提供适当的处理,有两个部分。

- (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];
...

UIImagePickerController 本身呈现视图控制器,因此此委托适用于堆栈上的所有演示者。

viewWillAppear 确保每当呈现的视图控制器在其上方消失时,该视图控制器本身总是被重置。

于 2014-03-21T16:49:29.690 回答
4

你能试试这个。我认为 needsStatusBarApperanceUpdate 会起作用。

1 -Set UIViewControllerBasedStatusBarAppearance to NO.
2- Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
3- [self setNeedsStatusBarAppearanceUpdate];
于 2013-09-25T20:35:08.523 回答
3

我有同样的问题。添加信息 plist:“查看基于控制器的状态栏外观”,值为“NO”

此处示例https://stackoverflow.com/a/19211669

这个解决方案对我有用。

于 2014-02-28T11:16:31.150 回答
2

尝试这个 ....

这在两种情况下都有效,即您是否使用 presentModalViewController 和 pushViewController

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;

委托方法

-(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];
}
于 2013-12-05T13:19:43.753 回答
2

以上所有答案都可以,可以提供帮助。

我在管理不同 iOS 版本下运行的应用程序时遇到了同样的问题。

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];

然后,在委托中:

- (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];
}
于 2014-12-10T09:25:11.067 回答
2

用于隐藏 UIImagePicker 中的状态栏:

-

 (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

当 UIImagePicker 被解除以隐藏视图控制器中的状态栏时,使用以下代码:

-(void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:YES];

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}
于 2013-10-27T11:08:52.163 回答
2

以上解决方案都不适合我。

我将 UIImagePickerController 呈现为模态视图控制器。关闭 UIImagePickerController 后,状态栏状态为:

[UIApplication sharedApplication].statusBarOrientation = 0 (UIDeviceOrientationUnknown)
[UIApplication sharedApplication].statusBarFrame = { 0, 0, 0, 0}

为我解决问题的解决方案是在解除 UIImagePickerController 后恢复 statusBarOrientation:

UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
[self.viewController presentViewController:cameraUI animated:true completion:^(void){ }];

...

[self.viewController dismissViewControllerAnimated:animated completion:^(void){
    [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
}];
于 2014-06-20T09:24:21.430 回答
2

以上所有对我都不起作用。我通过将演示样式更改为:

imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
于 2014-06-04T10:34:05.720 回答
2

此代码帮助我自定义状态栏样式。

编辑:如果“查看基于控制器的状态栏外观”== YES,则此解决方案有效

@implementation UIImagePickerController (IOS7_StatusBarStyle)

-(UIViewController*)childViewControllerForStatusBarStyle
{
   return nil;
}

-(UIStatusBarStyle)preferredStatusBarStyle
{
   return UIStatusBarStyleLightContent;
}

@end
于 2014-08-12T08:55:36.237 回答
2

这可能是一个错误。我通过将“基于视图控制器的状态栏外观”设置为 YES 并在每个视图控制器中粘贴以下代码来解决问题:

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

然后我的应用程序按预期运行。

于 2013-09-19T11:15:52.153 回答
2

另一种解决方案可能适用于某些情况。

let imagePicker =  UIImagePickerController()
imagePicker.sourceType = .PhotoLibrary
imagePicker.navigationBar.barStyle = .Black
于 2015-12-22T22:40:12.570 回答
1

我尝试在 iOS7 的 UIImagePickerController 中隐藏状态栏,但我仍然不知道该怎么做。我用

- (void)viewWillAppear:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES
                                        withAnimation:UIStatusBarAnimationNone];
}

在调用 UIImagePickerController 的 ViewController 中,并在 plist 文件中设置“基于视图控制器的状态栏外观 = NO”。希望这能有所帮助。

于 2013-09-22T07:07:18.123 回答
1

这为我解决了它......:

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [picker dismissViewControllerAnimated:YES completion:nil];
}
于 2014-02-01T10:05:22.860 回答
1

这里没有什么特别解决我遇到的问题(也许OP也有),所以我想我会分享我的答案。而不是隐藏我认为是错误解决方案的状态栏(我注意到它有时会使我的应用程序处于状态栏不应该隐藏的状态)。相反,我选择尝试与UIStatusBarStyles.

当 UIImagePickerController 显示其视图时,我将状态栏样式设置为默认值,因为默认背景颜色是浅灰色。

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}

然后,当图像选择器被关闭时,我将其设置回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];
}
于 2014-03-03T20:41:10.550 回答
1

使用默认的 iOS 8 行为,当我想要隐藏状态栏时,我遇到了问题。

presentPopover我找到的解决方案是,在从我的视图控制器调用之后,我直接做了:

    [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate) withObject:nil afterDelay:0.01];

我还必须将其添加到我的主视图控制器中:

- (UIViewController *)childViewControllerForStatusBarHidden
{
    return nil;
}
于 2014-11-12T17:01:21.380 回答
1

尝试这个 :

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;

在协议实现中,使用这个:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}
于 2013-11-02T08:53:20.317 回答
1

[self setNeedsStatusBarAppearanceUpdate]当您的呈现视图控制器重新出现时,您是否尝试过调用?

于 2013-09-18T19:10:49.600 回答
1

在这种情况下,我们使用 2 个步骤

第一步:添加 info.plist:“查看基于控制器的状态栏外观”,值为“NO”

在第二步:使用/调用此代码与 UIImagePickerController 的委托

 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
     if([navigationController isKindOfClass:[UIImagePickerController class]])
         [[UIApplication sharedApplication] setStatusBarHidden:YES]; 
 }

在 IOS-7 的情况下,增加一项功能

- (BOOL)prefersStatusBarHidden
{
    return YES;
}
于 2014-04-19T10:48:17.967 回答
1

从 iOS 8.1 开始,他们似乎终于修复了这个错误!我能够从我的代码中删除我使用的所有解决方法。

于 2014-11-05T05:09:48.153 回答
1

所以我遇到了这个问题,我可以通过简单地实现一个委托函数来解决它。我的状态栏的背景是黑色的,所以我的应用程序的 UIStatusBarStyle 是 .LightContent。当我展示 UIImagePickerController 从设备存储中选择照片时,状态栏很好。然而,在点击进入诸如“相机胶卷”或“收藏夹”之类的目录时,有效地推送到导航堆栈上,状态栏就消失了。选择照片后,根本没有状态栏;在关闭另一个模态视图控制器时,只有电池存在,表明状态栏的其余部分也可能是黑色的。

我尝试了其他一些解决方案,例如扩展 UIImagePickerController,但在 Swift 中,您不能使用扩展来覆盖。然后我尝试继承 UIImagePickerController 并尝试在 viewWillAppear() 上隐藏其状态栏并在 viewWillDisappear 上取消隐藏状态栏。我可以通过 .Slide 动画看到状态栏隐藏,但由于在选择目录时状态栏不可见,因此我无法看到状态栏取消隐藏。同样,在关闭模式视图控制器后,绿色电池又回来了,状态栏的其余部分不可见。我也尝试过覆盖 prefersStatusBarHidden(),但从未调用过该函数,因此我尝试调用 setNeedsStatusBarAppearanceUpdate() 以确保系统调用了 prefersStatusBarHidden(),但仍然没有调用它。还,有建议在委托方法navigationController willShowViewController 上将状态栏设置为隐藏。再一次,这一切只是隐藏状态栏,这并不能解决问题。事实证明,状态栏样式似乎在推送到 UIImagePickerController 的导航堆栈时发生了变化。为了彻底解决这个问题,我不必编写扩展或子类 UIImagePickerController。您需要做的就是设置委托并将状态栏样式设置为保持不变。这种添加使它好像问题从未存在过。似乎状态栏样式在推送到 UIImagePickerController 的导航堆栈时发生了变化。为了彻底解决这个问题,我不必编写扩展或子类 UIImagePickerController。您需要做的就是设置委托并将状态栏样式设置为保持不变。这种添加使它好像问题从未存在过。似乎状态栏样式在推送到 UIImagePickerController 的导航堆栈时发生了变化。为了彻底解决这个问题,我不必编写扩展或子类 UIImagePickerController。您需要做的就是设置委托并将状态栏样式设置为保持不变。这种添加使它好像问题从未存在过。

let pickerController = UIImagePickerController()
pickerController.delegate = self

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
        UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: false)
    }
于 2016-01-07T07:42:38.127 回答
-1

我实际上找到了一种在 Image Picker 中设置状态栏背景颜色的更好方法。基本上你需要将 navigationBar 中的 backgroundImage 设置为 nil,因为在 Image Picker 中默认有一个 backgroundImage 作为白色图像。

于 2016-01-22T15:48:16.637 回答