【问题标题】:UIImagePickerController status bar issue in crop裁剪中的 UIImagePickerController 状态栏问题
【发布时间】:2025-12-15 15:05:01
【问题描述】:

我使用UIViewControllerBasedStatusBarAppearancepreferredStatusBarStyle 来管理状态栏的颜色和外观。

我的应用允许用户从他的相机胶卷中选择一张照片,并使用UIImagePickerController 的原生裁剪选项将其裁剪为正方形。

所以我推送UIImagePickerController 并启用编辑以获取裁剪屏幕。
问题是,我希望相册和照片视图的状态栏为白色,而对于裁剪视图,我想隐藏状态栏。

我怎么能用 preferredStatusBarStyle 做到这一点?

直到现在我为UIImagePickerController创建了一个类别并实现了:

- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}  

这确实将照片中的状态栏设置为白色,但是在裁剪视图时,状态栏变成黑色,这对我来说可能很好,因为我想隐藏它并且背景是黑色的所以你不能看到它,但是电池指示灯是绿色的!所以你只能在状态栏中看到电池指示灯!

我该如何解决?如何仅在裁剪视图中隐藏状态栏?

【问题讨论】:

    标签: ios objective-c uiimagepickercontroller statusbar


    【解决方案1】:

    你必须在这里做一些侦探工作,但我可以给你一个线索。

    我建议继承 UIImagePickerController 并根据显示的子控制器返回您的状态栏首选项。

    UIViewController 有两种方法可以让您控制状态栏的可见性和外观:

    - (BOOL)prefersStatusBarHidden;
    - (UIStatusBarStyle)preferredStatusBarStyle
    

    只需覆盖它们,无需调用super

    您可以访问子类中的视图控制器堆栈,因此您可以根据堆栈上的控制器数量选择状态栏的首选样式和可见性。

    我感觉 UIKit 会在每次新的子控制器压入堆栈时 ping preferredStatusBarStyleprefersStatusBarHidden

    如果没有,那么你可以通过调用来强制 UIKit 更新状态栏:

    [self setNeedsStatusBarAppearanceUpdate]
    

    由于UIImagePickerControllerUINavigationController 的子类,您可以为其分配自己的委托,监控新控制器何时压入堆栈并调用上面建议的代码。

    【讨论】:

    • 但我的问题是我不知道 UIImagePickerController 正在推送哪些控制器,它都是私有的。例如,它可以在堆栈中包含多个视图控制器:相册、照片和裁剪。如果我只想隐藏裁剪控制器中的状态栏,我怎么知道?
    • 对,你可以使用NSStringFromClass(self.topViewController.class) 来获取私有类的字符串名称。这样您就可以识别控制器。
    • 我想你会发现父视图控制器的prefersStatusBarHidden 不会在孩子被推送时再次调用,除非使用setNeedsStatusBarAppearanceUpdate
    • @smallduck 今天看了我的回答,我觉得你是完全正确的。
    【解决方案2】:

    类似于Andy 的帖子,是的,子类化UIImagePickerController 曾经是被禁止的,但现在是允许的。不过,尝试覆盖 prefersStatusBarHiddenpreferredStatusBarStyle 时会出现一些意外问题。

    注意UIImagePickerControllerUINavigationController 的子类,因此它本身就是子视图控制器的容器。容器视图控制器如何控制状态栏对其子项的可见性和样式是通过覆盖childViewControllerForStatusBarHiddenchildViewControllerForStatusBarStyle。一般UINavigationController 不会实现这些,通常会覆盖它们以返回当前可见的视图控制器。

    在这种情况下,您不控制子视图控制器,您的选择器子类可以覆盖这些方法以返回 nil,然后您的 prefer 方法的实现应该接管。从理论上讲,您只需让它们在正确的时间返回您需要的东西,但正如我的经验所证明的那样,UIImagePickerController 和状态栏样式有些可疑。


    对于我自己的 UIImagePickerController 子类,我不关心子视图控制器给定它的自定义 UI,但我已经尝试从 childViewController.. 返回 nil 并覆盖 prefer 方法。我发现控制可见性可以正常工作,但是选择器中有一些东西可以抵消我的子类从preferredStatusBarStyle 返回LightContent。见my own question

    【讨论】: