UIImagePickerController 打破状态栏外观

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

在我的应用程序中,我呈现一个 VC,它呈现一个 UIImagePickerController

问题是这样的:

  • 在提供照片选择器之后,当选择照片库时,状态栏文本的颜色会发生变化。
  • 然后一次,解散 UIImagePickerController,状态栏间距 更改我的应用程序的其余部分和其他控制器的所有导航栏显示在状态栏下面。

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

35795 次浏览

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

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

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

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。

这可能是个窃听器。我解决了这个问题,设置“查看控制器为基础的状态栏外观”设置为 YES,并在每个视图控制器粘贴以下代码:

- (BOOL)prefersStatusBarHidden
{
return YES;
}

然后我的应用程序就会像预期的那样运行。

我也遇到了同样的问题。

这是我的解决办法。 将其放在视图控制器的 viewWillAppear 中,从该控制器中打开图像 pickerview

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


[[UIApplication sharedApplication] setStatusBarHidden:YES];


}

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

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

在 ViewController 中调用 UIImagePickerController,并在 plist 文件中设置“ View controller-based status bar look = NO”。希望这个能帮上忙。

以上所有的解决方案对我来说都不管用,但是通过结合 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...

你能试试这个吗? 我认为需要 StatusBarApperanceUpdate 可以工作。

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

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


}

试试这个:

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

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

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

试试这个。

这在两种情况下都可以工作,即是否使用 presModalViewController 和 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];
}

这解决了我的问题:

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

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

这里的例子 https://stackoverflow.com/a/19211669

这个方法对我很有效。

这里没有明确地修复我正在遇到的问题(也许 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];
}

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

- (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 确保这个视图控制器本身总是重置,只要呈现的视图控制器在它上面解除。

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

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

接受的答案将工作,如果您有“查看控制器为基础的状态栏外观”设置为 NO 在您的。普利斯特文件。如果确实需要控制其他视图控制器中的状态栏,并将该选项设置为 YES,那么另一种使 UIImagePickerController 正确运行的方法是对它进行子类化

// .h
@interface MYImagePickerController : UIImagePickerController
@end


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

以上这些对我来说都不起作用,我通过改变演讲风格来解决这个问题:

imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;

以上的方法对我都不管用。

我将 UIImagePickerController 作为模态视图控制器:

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

解决这个问题的方法是在解除 UIImagePickerController 之后恢复 statusBarOrient:

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


...


[self.viewController dismissViewControllerAnimated:animated completion:^(void){
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
}];

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

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

@implementation UIImagePickerController (IOS7_StatusBarStyle)


-(UIViewController*)childViewControllerForStatusBarStyle
{
return nil;
}


-(UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}


@end

从 iOS8.1开始,他们似乎终于修复了这个 bug!我能够从我的代码中删除所有我使用的变通方法。

使用默认的 iOS8行为,当我想要隐藏状态栏时,出现了问题。

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

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

我还不得不把它添加到我的主视图控制器中:

- (UIViewController *)childViewControllerForStatusBarHidden
{
return nil;
}

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

我在管理在 不同的 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];
}

在某些情况下,另一种解决方案可能会奏效。

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

所以我遇到了这个问题,我能够通过简单地实现一个委托函数来解决它。我的状态栏的背景是黑色的,因此我的应用程序的 UIStatusBarStyle 是黑色的。LightContent.当我展示 UIImagePickerController 以从设备存储中选择照片时,状态栏没有问题。但是,当点击“ Camera Roll”或“ Favorites”之类的目录时,状态栏就会消失,从而有效地推到导航堆栈上。在选择一张照片时,根本没有状态栏; 在取消另一个模态视图控制器时,只有电池出现,表明状态栏的其余部分也可能是黑色的。

我尝试了其他一些解决方案,比如扩展 UIImagePickerController,但是在 Swift 中,不能使用扩展重写。然后我尝试子类化 UIImagePickerController,并试图在 viewWillAppear ()上隐藏它的状态栏,在 viewWillDisaper 上取消隐藏状态栏。我可以看到状态栏隐藏了一个。幻灯片动画,但是由于状态栏在选择目录时是不可见的,我无法看到状态栏显示。同样,绿色的电池返回了状态栏的其余部分,这些状态栏在取消模态视图控制器时是不可见的。我还尝试重写 ferences sStatusBarHidden () ,但是这个函数从来没有被调用过,所以我尝试调用 setNeedsStatusBarApplicaranceUpdate ()来确保系统调用了 ferences sStatusBarHidden () ,但是它仍然没有被调用。此外,还有一个建议,即设置隐藏在委托方法导航中的状态栏 Controller will ShowViewController。同样,这样做只会隐藏状态栏,而这并不能解决问题。事实证明,状态栏样式似乎是在推送到 UIImagePickerController 的导航堆栈时更改的。为了完全解决这个问题,我不必编写扩展或子类 UIImagePickerController。您所需要做的就是设置委托并设置状态栏样式以保持不变。这样一来,问题就好像从未存在过一样。

let pickerController = UIImagePickerController()
pickerController.delegate = self


func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: false)
}

我实际上找到了一个更好的方法来设置状态栏背景颜色在图像选择器。基本上,您需要将导航栏中的 backoundImage 设置为 nil,因为 Image Picker 中的默认设置是将 backoundImage 设置为白色 Image。