【问题标题】:iOS 7 Status bar with Phonegap带有 Phonegap 的 iOS 7 状态栏
【发布时间】:2013-10-13 03:18:11
【问题描述】:

在 iOS 7 中,Phonegap 应用程序将出现在状态栏下方。这会使点击位于屏幕顶部的按钮/菜单变得困难。

是否有人知道如何在 iOS 7 上的 Phonegap 应用程序中解决此状态栏问题?

我尝试使用 CSS 来抵消整个网页,但它似乎不起作用。 有没有办法像偏移整个 UIWebView 或者只是让状态栏的行为像在 iOS6 中一样?

谢谢

【问题讨论】:

  • “状态栏问题”到底是什么?有没有要重现的示例代码?
  • @ShivanRaptor 在 iOS 7 中,状态栏现在是视图的一部分,所以如果你有以前的 iOS 版本在屏幕顶部的东西,现在它在状态栏下方,不会自动推到它的正下方,这可能会导致一些问题。我的建议是为您的内容创建一个包装器,并将 margin-top 设置为 20px。
  • @AndrewLively - 当页面滚动时这实际上不起作用,有没有办法移动 UIWebView?

标签: ios cordova uiwebview ios7 statusbar


【解决方案1】:

我在另一个帖子上找到了答案,但如果其他人想知道,我会回答这个问题。

只需将MainViewController.m 中的viewWillAppear 替换为:

- (void)viewWillAppear:(BOOL)animated {
    // View defaults to full size.  If you want to customize the view's size, or its subviews (e.g. webView),
    // you can do so here.
    // Lower screen 20px on ios 7
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        CGRect viewBounds = [self.webView bounds];
        viewBounds.origin.y = 20;
        viewBounds.size.height = viewBounds.size.height - 20;
        self.webView.frame = viewBounds;
    }
    [super viewWillAppear:animated];
}

【讨论】:

  • 还有其他人在使用 In App Browser 插件吗?如果我将 In App Browser 配置为“presentationstyle=fullscreen”,则关闭浏览器后会出现空白底部边距。看起来边距与 InAppBrowser 工具栏的高度相同。将演示文稿类型设置为“pagesheet”可以在 iPad 上解决此问题,但 iPhone 似乎总是使用“全屏”。有什么解决方法吗?
  • 非常感谢您的回答——但是同样的问题也适用于 PhoneGap inApp 浏览器——它也覆盖了状态栏。有什么想法吗?
  • 是的,我们使用的是旧版本的 Cordova (2.3.0),要解决这个问题,您必须设置 webViewBounds.origin.y = 20;在 createViewsWithOptions 中。另外,查看是否正在设置背景颜色并使用它。对 iOS7 及更高版本进行版本检查,就像 LudWig Kristoffersson 的出色回答一样。
  • 另外 - 如果您使用 InAppBrowser,每次返回时视图都会重新初始化。因此,谨慎的做法是在 MainViewController.m 中添加一个表明它已经运行的标志。
  • 因为此代码在 viewWillAppear 中运行,如果您的 PhoneGap/Cordova 应用程序显示其他本机视图(如相机捕获对话框)并返回到此视图,您将遇到此解决方案的问题。我的解决方法是将“viewBounds”初始化为“[self.view bounds]”而不是“[self.webView bounds]”。
【解决方案2】:

除了 Ludwig Kristoffersson 的调整大小修复,我建议更改状态栏颜色:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        CGRect viewBounds = [self.webView bounds];
        viewBounds.origin.y = 20;
        viewBounds.size.height = viewBounds.size.height - 20;
        self.webView.frame = viewBounds;
    }
    self.view.backgroundColor = [UIColor blackColor];
}
-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}

【讨论】:

  • 工作得很好 :) 非常感谢 :)
  • 完美 - 这对我来说是更好的解决方案。
  • 此修复在 Xcode 构建后在本地工作,但在我进行 phonegap 构建后不起作用。有任何想法吗?我有一个用 phonegap 2.9 构建的 ios 应用程序
  • 此解决方案有效,但我遇到了全屏视频问题,我找到了另一个解决方案,解决了我的问题zsprawl.com/iOS/2013/10/fixing-the-phonegap-status-bar-in-ios7
  • @KirankumarSripati 实际上我的最后一个解决方案是我希望这对你有用 NSInteger screenSize = 0; //全局 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { CGRect viewBounds = [self.webView bounds]; viewBounds.origin.y = 20; if(screenSize == 0) { viewBounds.size.height = viewBounds.size.height - 20; screenSize = viewBounds.size.height; } self.webView.frame = viewBounds;我这样做是因为我的应用每次进入全屏时都会调整大小
【解决方案3】:

请为 phonegap 安装该插件:https://build.phonegap.com/plugins/505

并使用如下正确设置来控制 webview 的覆盖:

<preference name="StatusBarOverlaysWebView" value="false" />

对我来说,使用 Phonegap 3.3.0 就可以了。

更多信息,在 Github 项目页面: https://github.com/phonegap-build/StatusBarPlugin

【讨论】:

  • 非常感谢您的回答!!我正在尝试使用此插件:build.phonegap.com/plugins/715,问题是名称相同。但从不适合我。非常感谢!!
  • 说实话,我不记得在你提到的这个之前我有没有试过。
【解决方案4】:

要隐藏状态栏,在MainViewController.m函数-(void)viewDidUnload下的文件中添加如下代码

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

【讨论】:

  • 这样就完成了。它将隐藏状态栏,使您的应用程序全屏显示。我只在模拟器上对此进行了测试,但稍后在我的 iPhone 和 iPad 上运行构建时会报告。
  • 在 iPad 2 上的 iOS 上为我工作
  • 这在 iPad Air iOS 7.1.2 上运行良好,无需任何更改或插件。很好的答案,谢谢!
  • 这完全忽略了 Apple 在人机界面指南中所说的关于“沉浸式全屏模式”的所有内容......仅仅因为您在 iOS 上使用包装器并不意味着您可以忽略设计模式...:/
【解决方案5】:

Answer https://stackoverflow.com/a/19249775/1502287 为我工作,但我不得不对其进行一些更改以使其与相机插件(可能还有其他插件)和带有“height = device-height”的视口元标记(不设置高度)一起使用部分会导致键盘出现在我的情况下的视图上,沿途隐藏一些输入)。

每次您打开相机视图并返回您的应用时,都会调用 viewWillAppear 方法,并且您的视图会缩小 20 像素。

另外,视口的设备高度将包括额外的 20 像素,使内容可滚动并且比 web 视图高 20 像素。

这是相机问题的完整解决方案:

在 MainViewController.h 中:

@interface MainViewController : CDVViewController
@property (atomic) BOOL viewSizeChanged;
@end

在 MainViewController.m 中:

@implementation MainViewController

@synthesize viewSizeChanged;

[...]

- (id)init
{
    self = [super init];
    if (self) {
        // On init, size has not yet been changed
        self.viewSizeChanged = NO;
        // Uncomment to override the CDVCommandDelegateImpl used
        // _commandDelegate = [[MainCommandDelegate alloc] initWithViewController:self];
        // Uncomment to override the CDVCommandQueue used
        // _commandQueue = [[MainCommandQueue alloc] initWithViewController:self];
    }
    return self;
}

[...]

- (void)viewWillAppear:(BOOL)animated
{
    // View defaults to full size.  If you want to customize the view's size, or its subviews (e.g. webView),
    // you can do so here.
    // Lower screen 20px on ios 7 if not already done
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7 && !self.viewSizeChanged) {
        CGRect viewBounds = [self.webView bounds];
        viewBounds.origin.y = 20;
        viewBounds.size.height = viewBounds.size.height - 20;
        self.webView.frame = viewBounds;
        self.viewSizeChanged = YES;
    }
    [super viewWillAppear:animated];
}

现在对于视口问题,在您的 deviceready 事件侦听器中,添加以下内容(使用 jQuery):

if (window.device && parseFloat(window.device.version) >= 7) {
  $(window).on('orientationchange', function () {
      var orientation = parseInt(window.orientation, 10);
      // We now the width of the device is 320px for all iphones
      // Default height for landscape (remove the 20px statusbar)
      var height = 300;
      // Default width for portrait
      var width = 320;
      if (orientation !== -90 && orientation !== 90 ) {
        // Portrait height is that of the document minus the 20px of
        // the statusbar
        height = document.documentElement.clientHeight - 20;
      } else {
        // This one I found experimenting. It seems the clientHeight
        // property is wrongly set (or I misunderstood how it was
        // supposed to work).
        // I don't know if it is specific to my setup.
        width = document.documentElement.clientHeight + 20;
      }
      document.querySelector('meta[name=viewport]')
        .setAttribute('content',
          'width=' + width + ',' +
          'height=' + height + ',' +
          'initial-scale=1.0,maximum-scale=1.0,user-scalable=no');
    })
    .trigger('orientationchange');
}

这是我用于其他版本的视口:

<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0" />

现在一切正常。

【讨论】:

  • 任何没有 Jquery @dieppe 的方法
  • 只需将此代码添加到 CDVCamera.m 中的 - (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info {} 方法,也可以解决相机问题。 NSLog(@"关闭的相机"); [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
  • 伙计,我不知道该说什么谢谢!我一直在努力解决相机的 20px 缩小问题,直到现在才找到解决方案......
【解决方案6】:

尝试在 XCode 中进入应用程序的 (app name)-Info.plist 文件并添加密钥

view controller-based status bar appearance: NO
status bar is initially hidden : YES

这对我来说没有问题。

【讨论】:

  • 对我来说,这适用于本地构建的模拟器,但不适用于远程构建的 iPad。在模拟器和 iPad 上使用 PG 3.1 进行构建和 iOS7。
  • @PerQuestedAronsson 您可能想尝试在 iPad 上本地构建它。我正在使用带有 phonegap 3.1 的 iPad iOS7 没有问题。
【解决方案7】:

对于 Cordova 3.1+,有一个插件可以处理 iOS 7+ 状态栏的行为变化。

这很好地记录了here,包括如何将状态栏恢复到其 iOS7 之前的状态。

要安装插件,运行:

cordova plugin add org.apache.cordova.statusbar

然后将其添加到 config.xml

<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarStyle" value="default" />

【讨论】:

【解决方案8】:

我通过安装org.apache.cordova.statusbar 并添加我的顶部config.xml 来解决我的问题:

<preference name="StatusBarOverlaysWebView" value="false" /> 
<preference name="StatusBarBackgroundColor" value="#000000" />
<preference name="StatusBarStyle" value="lightcontent" />

这些配置仅适用于 iOS 7+

参考: http://devgirl.org/2014/07/31/phonegap-developers-guid/

【讨论】:

    【解决方案9】:

    查看新的 Cordova 状态栏插件,该插件解决了该问题。 http://docs.icenium.com/troubleshooting/ios7-status-bar#solution 选项#3

    【讨论】:

      【解决方案10】:

      如果检测到 iOS7,我使用以下代码向正文添加一个类。然后我设置该类的样式,在容器顶部添加20px 边距。确保您已安装“设备”插件,并且此代码位于“设备就绪”事件中。

      通过阅读,我听说 Phonegap 的下一次更新(我相信是 3.1)将更好地支持对 iOS7 状态栏的更改。所以这可能只是作为短期修复需要。

      if(window.device && parseFloat(window.device.version) >= 7){
        document.body.classList.add('fix-status-bar');
      }
      

      【讨论】:

        【解决方案11】:

        Ludwig's answer 为我工作。

        对于使用他的答案并且现在希望更改白边颜色的任何人(可能看起来微不足道,但让我难过),请参阅:

        How can I change the UIWebView background color after sliding down UIWebView to fix the iOS7 status bar overlay issue?

        【讨论】:

          【解决方案12】:

          另一种方式是向后兼容。根据iOS 7 制作HTML(顶部有额外的20px 边距),以使full screen 看起来并为iOS &lt; 7.0 剪掉额外的边距。 MainViewController.m 中类似以下内容:

          - (void)viewDidLoad
          {
            [super viewDidLoad];
          
            if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0) {
              CGRect viewBounds = [self.webView bounds];
              viewBounds.origin.y = -20;
              viewBounds.size.height = viewBounds.size.height + 20;
              self.webView.frame = viewBounds;
            }
          }
          

          此解决方案不会在 iOS 7.0 及更高版本的顶部留下黑条,现代 iOS 用户会发现它很奇怪且

          【讨论】:

            【解决方案13】:

            didFinishLaunchingWithOptions 事件中的 AppDelegate.m 中编写以下代码(正好在其最后一行代码“return YES;”之前):

            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
            {
                [application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
            }
            

            我会等待您的反馈! :)

            【讨论】:

            • 这段代码看起来可以很好地隐藏状态栏并解决问题,我昨天也环顾四周,发现基本上调整了 UIWebView 大小并将其向下移动的代码我添加了这个一个答案:)
            • 太好了。我的代码只是使用一种简单易行的方法来完成它!我们所有人都在用不同的方法做同样的事情:)
            【解决方案14】:

            如果我们为图片库使用相机插件,状态栏会回来,所以要解决这个问题,请添加此行

             [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
            

            - (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info {...}
            

            插件列表中 CVDCamera.m 中的函数

            【讨论】:

              【解决方案15】:

              didFinishLaunchingWithOptions 事件开始时在 AppDelegate.m 中编写以下代码。

              CGRect screenBounds = [[UIScreen mainScreen] bounds]; // Fixing status bar ------------------------------- NSArray *vComp = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."]; if ([[vComp objectAtIndex:0] intValue] >= 7) { // iOS 7 or above CGRect newWebViewBounds = CGRectMake( 0, 20, screenBounds.size.width, screenBounds.size.height-20 ); screenBounds = newWebViewBounds; } // ------------------------------- Fixing status bar End

              并针对 iOS 7 及更高版本进行修复。

              【讨论】:

                【解决方案16】:

                要使状态栏在纵向中可见但在横向中隐藏(即全屏),请尝试以下操作:

                MainViewController.h:

                @interface MainViewController : CDVViewController
                @property (atomic) NSInteger landscapeOriginalSize;
                @property (atomic) NSInteger portraitOriginalSize;
                @end
                

                MainViewController.m:

                @implementation MainViewController
                
                @synthesize landscapeOriginalSize;
                @synthesize portraitOriginalSize;
                
                ...
                
                - (void)viewWillAppear:(BOOL)animated
                {
                    // View defaults to full size.  If you want to customize the view's size, or its subviews (e.g. webView),
                    // you can do so here.
                
                    [super viewWillAppear:animated];
                
                    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
                }
                
                - (void)orientationChanged:(NSNotification *)notification {
                    [self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
                }
                
                - (void)viewDidDisappear:(BOOL)animated {
                    [[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
                }
                
                - (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {
                    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
                        CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
                        CGRect frame = self.webView.frame;
                
                        switch (orientation)
                        {
                            case UIInterfaceOrientationPortrait:
                            case UIInterfaceOrientationPortraitUpsideDown:
                            {
                                if (self.portraitOriginalSize == 0) {
                                    self.portraitOriginalSize = frame.size.height;
                                    self.landscapeOriginalSize = frame.size.width;
                                }
                                frame.origin.y = statusBarFrame.size.height;
                                frame.size.height = self.portraitOriginalSize - statusBarFrame.size.height;
                            }
                                break;
                
                            case UIInterfaceOrientationLandscapeLeft:
                            case UIInterfaceOrientationLandscapeRight:
                            {
                                if (self.landscapeOriginalSize == 0) {
                                    self.landscapeOriginalSize = frame.size.height;
                                    self.portraitOriginalSize = frame.size.width;
                                }
                                frame.origin.y = 0;
                                frame.size.height = self.landscapeOriginalSize;
                            }
                                break;
                            case UIInterfaceOrientationUnknown:
                                break;
                        }
                
                        self.webView.frame = frame;
                    }
                }
                
                - (void)viewDidLoad
                {
                    [super viewDidLoad];
                
                    // Do any additional setup after loading the view from its nib.
                
                    // Change this color value to change the status bar color:
                    self.view.backgroundColor = [UIColor colorWithRed:0/255.0f green:161/255.0f blue:215/255.0f alpha:1.0f];
                }
                

                这是我在这个和链接的 StackOverflow 讨论中找到的内容、Cordova StatusBar 插件中的一些代码(以免硬编码 20px 值)和我的一些咒语(我不是iOS 开发人员,所以我摸索到了这个解决方案)。

                【讨论】:

                  【解决方案17】:

                  首先,在您的项目中添加设备插件。插件 ID 是:org.apache.cordova.device 和存储库是:https://github.com/apache/cordova-plugin-device.git

                  之后使用此函数并在每个页面或屏幕上调用它:-

                  function mytopmargin() {
                      console.log("PLATform>>>" + device.platform);
                      if (device.platform === 'iOS') {
                          $("div[data-role='header']").css("padding-top", "21px");
                          $("div[data-role='main']").css("padding-top", "21px");
                      } else {
                          console.log("android");
                      }
                  }
                  

                  【讨论】:

                    【解决方案18】:

                    控制状态栏背景的最佳方式 - 2017

                    经过不断的挫折,在互联网上进行了大量搜索,这些是您需要采取的步骤:

                    1. 确保您使用Status Bar Plugin
                    2. 将此设置添加到您的 config.xml:

                    1. onDeviceReady

                      上使用以下代码
                          StatusBar.show();
                          StatusBar.overlaysWebView(false);
                          StatusBar.backgroundColorByHexString('#209dc2');
                      

                    它适用于 iOS 和 Android。

                    祝你好运!

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2015-01-22
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2016-02-22
                      • 2013-12-02
                      • 2013-10-27
                      • 2013-08-14
                      相关资源
                      最近更新 更多