当前位置: 首页 > 知识库问答 >
问题:

替代基于视图控制器的状态栏外观

柴嘉禧
2023-03-14

我有一个应用程序,基于视图控制器的状态栏外观设置为YES。我的一些视图是深色的,一些视图是浅色的,应用程序有一个相当复杂的视图控制器层次结构,但它可以完美地将适当的方法子类化和重写,并与模式视图(捕捉呈现样式等)相结合。

然而,我需要一种全局的方式来查看顶部的特定项目(在状态栏后面,在我的应用程序边界内),就像顶部的个人热点/GarageBand录音/通话等栏一样。由于栏的背景颜色,我想在显示栏时覆盖状态栏的外观(它可以在应用程序中的任何地方显示,所以我子类化了UIWindow并将其演示文稿代码和视图直接放在那里)。该栏显示完全按照我想要的屏幕与轻内容状态栏(因为我的栏的文本是白色和背景是黑暗的),但看起来可怕的黑暗内容状态栏(不,我不能改变栏的颜色)。

我如何在全局覆盖“无论当前呈现的视图控制器是什么”的首选状态栏样式(当然,不遍历所有视图控制器中状态栏方法的所有实例),同时仍然使用基于视图控制器的状态栏外观?我的应用程序目标iOS8.0。

共有1个答案

裴英才
2023-03-14

我以一种非常杂乱(但有效)的方式结束了。它可能不适用于所有场景,但它适用于我的场景。我保持了视图的原样,没有碰过一个视图或控制器。

首先,我得到了当前显示的最顶层视图控制器。我使用了iPhone的代码——如何找到最顶层的视图控制器,并对其进行了一些修改,以处理导航控制器和选项卡栏控制器的情况:

+ (UIViewController*) topmostControllerForViewController:(__kindof UIViewController*)topController
{
    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }
    if([topController isKindOfClass:[UINavigationController class]]){
        UINavigationController *navController = topController;
        return [self topmostControllerForViewController:navController.visibleViewController];
    }
    if([topController isKindOfClass:[UITabBarController class]]){
        UITabBarController *tabController = topController;
        return [self topmostControllerForViewController:tabController.selectedViewController];
    }
    return topController;
}

+ (UIViewController*) topmostController
{
    __kindof UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
    return [self topmostControllerForViewController:topController];
}

然后我创建了一个没有视图的视图控制器(viewisnil)。在它的init方法(如果放入viewddLoad:中,在第一次调用中不起作用,因为它在转换过程中被调用,已经太晚了)中,我添加了以下内容:

self.modalPresentationCapturesStatusBarAppearance = YES;
self.modalPresentationStyle = UIModalPresentationOverCurrentContext;

这段代码允许我的“虚拟”视图(less)控制器处理所有的表示上下文,包括状态栏Appearance以及其他视图控制器在显示时发生的情况。在当前上下文中显示时,后面的视图控制器不会从视图层次结构中删除。如果我不这样做,它将被删除,屏幕将是黑色的(因为我没有任何视图,我希望显示以前的视图控制器)。

到现在为止,一直都还不错。然后,我正常地显示了我的栏,但同时,没有任何视图,而是以模式呈现了视图控制器。因为视图控制器没有任何视图,并且是在当前上下文中显示的,所以它在视觉上没有以任何方式出现,但由于它是一种模式演示,并且虚拟视图控制器被设置为捕获演示样式,因此它触发iOS向我的应用程序询问状态栏样式。我只是在视图控制器方法中设置了我想要的状态栏样式。

有个小问题。当我展示新的视图控制器时,系统在我以前的视图控制器的基础上添加了一个UITransitionView。如果有实际视图,它将位于过渡视图的顶部。过渡视图是完全透明的,但它启用了用户交互,并捕获了所有触摸事件,使我的应用程序在我关闭控制器之前没有响应。我需要我以前的视图控制器来接收触摸事件。我已经深入挖掘,找到了模态演示添加过渡视图的位置,并在过渡动画完成后演示视图控制器时将其删除:

for (UIView *view in self.subviews) {
        NSString *className = NSStringFromClass([view class]);
        if([className hasPrefix:@"UIT"] && className.length == 16){
            //this must be UITransitionView, but I'm not using it directly since it may interfere with private API usage and get app rejected by Apple.
            //now, we need to find another transition view inside this and remove it
            for (UIView *innerView in view.subviews) {
                className = NSStringFromClass([innerView class]);
                if([className hasPrefix:@"UIT"] && className.length == 16){
                    //this is the transition view that we need to remove
                    [innerView removeFromSuperview];
                } 
            }
        }
}

由于UITransitionView是一种私有视图类型,我不确定它是否会导致App Store出现问题,因此我通过检查第一个字母UIT并检查类名的长度,对UITransitionView进行了启发式检查。它不是防弹的,但似乎有效,不太可能返回假阳性。

现在一切正常。它很粗糙,将来可能会坏掉,尤其是在引擎盖下模式呈现发生变化的情况下。但请放心,它是有效的。

 类似资料:
  • 标题说明了一切。或者我在理解sdk时有一些非常错误的地方,或者苹果的sdk有一些非常错误的地方。 设置(info.plist)基于视图控制器的状态时..=是的,我可以通过调用setNeedsStatusBarEtc来隐藏我的状态栏动画等等。。。但是,我不能改变我喜欢的风格。当我将其设置为“否”时,我可以更改样式,但不能更改所有其他内容。。我该怎么办?怎么了?请帮帮我! 当基于控制器的状态...=Y

  • 我正在尝试修改状态栏的外观(将文本设置为白色/将样式设置为“灯光”)。通过将其添加到AppDelegate中,我成功地设置了背景色。swift文件: 但是,当我去更改状态栏的文本样式时,甚至在一般情况下更改此样式 我还试图通过nfo.plist修改状态栏,但是没有“基于视图控制器的状态栏外观”字段(见第二张图片)。此外,状态栏样式选项下没有“轻”样式选项(见下图):

  • 我需要根据视图控制器改变状态栏样式,所以在我的plist文件“基于视图控制器的状态栏外观”设置为是。 我有时需要隐藏状态栏! 我试图使用setStatusBarHidden,但它似乎只有在“基于视图控制器的状态栏外观”设置为NO时才能工作... 有没有办法隐藏状态栏?

  • 我有一个视图控制器,这是导航控制器的rootVc。 我需要为rootview控制器隐藏导航栏,因此我使用以下方法来隐藏它并使其重新出现。 我基本上是在rootVc中隐藏导航栏,并为所有其他视图控制器显示它。 但当我移除导航栏时,我看到我的内容正在状态栏下扩展 有办法解决这个问题吗?

  • 我的应用程序使用深色导航栏颜色。因此,我将状态栏的颜色设置为白色(因此对比度很好)。 我通过将barStyle设置为黑色(使状态栏为白色)并将barTint设置为我的深红色来实现这一点。完美地工作。 我展示了一个像这样的: 但是,显示的SafariViewController的状态栏仍为白色。这是一个问题,因为导航栏具有默认的白色透明iOS默认样式。所以状态栏基本上是不可见的。 我怎样才能解决这个

  • 我的项目中有多个故事板。我在一个故事板中有一个主页面浏览量控制器,我在一个单独的故事板中有一个安装视图控制器嵌入导航控制器。现在,当我从主页视图控制器中显示安装视图控制器导航控制器时,状态栏不会隐藏。但是当我将安装视图控制器故事板设置为info.plist中的主故事板文件库,并且安装视图控制器导航控制器是第一个呈现的视图时,状态栏将隐藏。我正在使用下面的代码隐藏状态栏。有人能告诉我当状态视图控制器