首页 文章

UIImagePickerController打破状态栏外观

提问于
浏览
137

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

在我的应用程序中,我提出了一个提供 UIImagePickerController 的VC .

问题是这样的:

  • 显示照片选择器后,选择照片库时,状态栏文本的颜色会发生变化 .

  • 然后, UIImagePickerController 被解除,我的应用程序的其余部分的状态栏间距发生变化,其他控制器的所有导航栏都显示在状态栏下 .

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

25 回答

  • 3

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

    希望它可以帮助某人

  • 2

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

    在调用图像选择器的视图控制器中,将您自己设置为图像选取器的委托 . (你可能已经这样做了)

    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替换为您要查找的任何样式 .

  • 4

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

    // .h
    @interface MYImagePickerController : UIImagePickerController
    @end
    
    // .m
    @implementation MYImagePickerController
    - (UIStatusBarStyle)preferredStatusBarStyle
    {
        return UIStatusBarStyleLightContent; // change this to match your style
    }
    @end
    
  • 1

    我遇到了同样的问题 .

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

    -(void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:YES];
    
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    
    }
    
  • 2

    你能试试吗?我认为needsStatusBarApperanceUpdate会起作用 .

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

    我发现这提供了正确的处理,有两个部分 .

    - (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确保每当呈现视图控制器在其上方解除时,该视图控制器本身总是被重置 .

  • 1

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

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

    这个解决方案适合我 .

  • 6

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

    - (BOOL)prefersStatusBarHidden
    {
        return YES;
    }
    

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

  • 1

    用于隐藏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];
    
    }
    
  • 1

    试试这个 ....

    这将适用于两种情况,即您是否使用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];
    }
    
  • 192

    上述解决方案均不适合我 .

    我将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;
    }];
    
  • 1

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

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

    @implementation UIImagePickerController (IOS7_StatusBarStyle)
    
    -(UIViewController*)childViewControllerForStatusBarStyle
    {
       return nil;
    }
    
    -(UIStatusBarStyle)preferredStatusBarStyle
    {
       return UIStatusBarStyleLightContent;
    }
    
    @end
    
  • 10

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

    我有同样的问题,必须管理在 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];
    

    然后,在代表中:

    - (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];
    }
    
  • 4

    另一种可能在某些情况下起作用的解决方案 .

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

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

  • 1

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

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

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

  • -1

    试试这个 :

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

    并在协议实现中,使用此:

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

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

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

    这里没有什么特别修复了我遇到的问题(也许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];
    }
    
  • 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;
    }
    
  • 1

    以上所有都不适合我 . 我通过将演示文稿样式更改为:

    imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
    
  • 1

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

  • 1

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

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

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

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

    - (UIViewController *)childViewControllerForStatusBarHidden
    {
        return nil;
    }
    
  • 2

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

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

    let pickerController = UIImagePickerController()
    pickerController.delegate = self
    
    func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
            UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: false)
        }
    
  • 2

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

相关问题