UIImagePickerController打破状态栏外观

时间:2013-09-18 19:08:34

标签: ios7

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

在我的应用中,我展示了一个展示UIImagePickerController

的VC

问题是这样的:

  • 显示照片选择器后,选择照片库时,状态栏文本的颜色会发生变化。
  • 然后,UIImagePickerController被解雇,状态栏间距 我应用程序其余部分的更改以及其他控制器的所有导航栏都显示在状态栏下。

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

25 个答案:

答案 0 :(得分:192)

上述解决方案都不适合我,但通过结合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...

希望它有助于某人

答案 1 :(得分: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替换为您要查找的任何样式。

答案 2 :(得分:10)

如果在.plist文件中将“基于控制器的状态栏状态显示”设置为“否”,则接受的答案将起作用。如果确实需要控制某些其他视图控制器中的状态栏并将此选项设置为YES,那么使UIImagePickerController正常运行的另一种方法是通过子类化它

// .h
@interface MYImagePickerController : UIImagePickerController
@end

// .m
@implementation MYImagePickerController
- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent; // change this to match your style
}
@end

答案 3 :(得分:6)

我遇到了同样的问题。

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

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

[[UIApplication sharedApplication] setStatusBarHidden:YES];

}

答案 4 :(得分:4)

你能试试吗?我认为needsStatusBarApperanceUpdate可以正常工作。

1 -Set UIViewControllerBasedStatusBarAppearance to NO.
2- Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
3- [self setNeedsStatusBarAppearanceUpdate];

答案 5 :(得分: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确保只要呈现视图控制器在其上方解除,该视图控制器本身就会被重置。

答案 6 :(得分:3)

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

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

此解决方案适合我。

答案 7 :(得分: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;
}];

答案 8 :(得分:2)

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

编辑:如果“查看基于控制器的状态栏外观”== YES

,此解决方案有效
@implementation UIImagePickerController (IOS7_StatusBarStyle)

-(UIViewController*)childViewControllerForStatusBarStyle
{
   return nil;
}

-(UIStatusBarStyle)preferredStatusBarStyle
{
   return UIStatusBarStyleLightContent;
}

@end

答案 9 :(得分: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];
}

答案 10 :(得分: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];
}

答案 11 :(得分:2)

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

let imagePicker =  UIImagePickerController()
imagePicker.sourceType = .PhotoLibrary
imagePicker.navigationBar.barStyle = .Black

答案 12 :(得分:2)

用于隐藏UIImagePicker中的状态栏:

-

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

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

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

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}

答案 13 :(得分:2)

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

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

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

答案 14 :(得分:1)

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

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

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

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

- (UIViewController *)childViewControllerForStatusBarHidden
{
    return nil;
}

答案 15 :(得分:1)

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

答案 16 :(得分:1)

所以我遇到了这个问题,我只需要实现一个委托功能就可以解决这个问题。我的状态栏的背景是黑色的,因此我的应用程序的UIStatusBarStyle是.LightContent。当我提出UIImagePickerController从设备存储中选择一张照片时,状态栏很好。但是,在点击诸如&#34;相机胶卷&#34;之类的目录时或者&#34;收藏夹&#34;有效地推入导航堆栈,状态栏消失了。选择照片后,根本没有状态栏;在关闭另一个模态视图控制器时,只有电池存在,表明状态栏的其余部分也可能是黑色的。

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

intmax_t

答案 17 :(得分: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];
}

答案 18 :(得分:1)

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

来解决了这个问题
imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;

答案 19 :(得分:1)

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

第一步:                 添加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;
}

答案 20 :(得分:1)

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

答案 21 :(得分:1)

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

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [picker dismissViewControllerAnimated:YES completion:nil];
}

答案 22 :(得分:1)

试试这个:

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

并在协议工具中使用:

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

答案 23 :(得分:1)

我尝试在iOS7中隐藏UIImagePickerController中的状态栏,但我仍然不知道如何做到这一点。我用

- (void)viewWillAppear:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES
                                        withAnimation:UIStatusBarAnimationNone];
}
调用UIImagePickerController的ViewController中的

,并在plist文件中设置“View controller-based status bar appearance = NO”。希望这可以提供帮助。

答案 24 :(得分:-1)

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