带Phonegap的iOS 7状态栏


91

在iOS 7中,Phonegap应用程序将显示在状态栏下方。这可能导致难以单击位于屏幕顶部的按钮/菜单。

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

我试图用CSS抵消整个网页,但似乎无法正常工作。有没有办法喜欢偏移整个UIWebView或只是使状态栏的行为像在iOS6中一样?

谢谢


“状态栏问题”到底是什么?有没有要复制的示例代码?
猛禽2013年

1
@ShivanRaptor在iOS 7中,状态栏现在是视图的一部分,因此,如果您的内容位于以前的iOS版本的屏幕顶部,则它现在位于状态栏的下方,而不是自动推到其下方。会引起一些问题。我的建议是为您的内容创建一个包装器,并设置20px的页边距顶部。
Andrew Lively 2013年

@AndrewLively-当页面滚动时,这实际上不起作用,是否可以移动UIWebView?
Luddig

Answers:


143

我在另一个线程上找到了答案,但是如果有人怀疑,我会回答这个问题。

只需将viewWillAppearin 替换为MainViewController.m

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

9
还有其他人将其与In App Browser插件一起使用吗?如果我将In App Browser配置为“ presentationstyle = fullscreen”,则在关闭浏览器后,底部空白会出现。边缘似乎与InAppBrowser工具栏的高度相同。将presentationtype设置为“ pagesheet”可以在iPad上解决此问题,但iPhone似乎总是使用“全屏”。任何解决方法?
保罗

1
非常感谢您的回答-但是,相同的问题也适用于PhoneGap inApp浏览器-它也覆盖了状态栏。有什么想法吗?
迈克尔

2
是的,我们使用的是Cordova的旧版本(2.3.0),要解决此问题,您必须将webViewBounds.origin.y = 20; 在createViewsWithOptions中。另外,请查看是否设置了背景色,然后进行尝试。就像针对LudWig Kristoffersson的出色回答一样,对iOS7及更高版本进行版本检查。
hnilsen 2013年

3
另外-如果您使用的是InAppBrowser,则每次返回时,视图都会重新初始化。因此,应谨慎地向MainViewController.m添加一个标志,表明该标志已被运行。
hnilsen 2013年

14
由于此代码在viewWillAppear中运行,因此如果PhoneGap / Cordova应用显示其他本机视图(如“摄像头捕获”对话框)并返回该视图,则该解决方案会遇到问题。对我来说,解决方法是将“ viewBounds”初始化为“ [self.view bounds]”,而不是“ [self.webView bounds]”。
克里斯·凯彻

37

除了路德维希·克里斯托弗森(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;
}

1
工作很棒:)非常感谢:)
rkaartikeyan 2013年

完美-对我来说这是更好的解决方案。
David Daudelin 2014年

此修补程序在Xcode构建之后在本地有效,但在我进行了phonegap构建之后则无法使用。有任何想法吗?我有一个使用phonegap 2.9构建的ios应用
DemitryT

此解决方案有效,但我在全屏视频上遇到了问题,但我又发现了另一个问题,它解决了我的问题 zsprawl.com/iOS/2013/10/fixing-the-phonegap-status-bar-in-ios7
magorich

1
@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; }我这样做是因为每次进入全屏模式时,我的应用都会调整大小
magorich 2014年

22

请安装用于phonegap的插件:https ://build.phonegap.com/plugins/505

并使用如下所示的正确设置来控制网络视图的覆盖:

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

对我而言,使用Phonegap 3.3.0可以正常工作。

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


非常感谢您的回答!!我正在尝试使用此插件:build.phonegap.com/plugins/715,问题是名称相同。但是永远不会为我工作。非常感谢!!
JabelMárquez2014年

老实说,我不记得我是否曾尝试过您提到的这一件事。
xdemocle 2014年

20

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

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

这样就可以了。它将隐藏状态栏,使您的应用全屏显示。我仅在模拟器上进行了测试,但是稍后在我的iPhone和iPad上运行构建时会报告。
罗布·埃文斯

在iPad 2上的iOS上为我工作
马克·威廉姆斯

在iPad Air iOS 7.1.2上这可以很好地工作,并且不需要任何更改或插件。好答案,谢谢!
Scriptlabs 2014年

这完全忽略了苹果在《人机界面指南》中所说的“沉浸式全屏模式”的所有内容……仅仅因为您在iOS之上使用包装器并不意味着您可以忽略设计模式……:/
jesses .co.tt 2015年

15

回答https://stackoverflow.com/a/19249775/1502287为我工作,但我必须对其进行一些更改,以使其与相机插件(可能还有其他插件)以及带有“ height = device-高度”(如果未设置高度部分,则在我的情况下,键盘将显示在视图上方,并在此过程中隐藏一些输入)。

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

此外,视口的设备高度将额外增加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).
        // Dunno if it's 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的任何方法
Arjun T Raj

只需将此代码添加到CDVCamera.m中的-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {}方法中,即可解决相机问题。NSLog(@“ CLOSED CAMERA”); [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
Arjun T Raj

伙计,我不知道该说些什么谢谢!我一直在为20px缩小问题而苦苦挣扎,直到现在都找不到解决方案……
tuks

6

尝试进入(app name)-Info.plistXCode中的应用文件并添加密钥

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

这对我毫无问题。


对我来说,这在具有本地版本的模拟器中有效,而在具有远程版本的iPad中则无效。使用PG 3.1进行构建,并在模拟器和iPad上使用iOS7。
Per Quested Aronsson

@PerQuestedAronsson您可能想尝试在iPad上本地构建它。我正在使用带phonegap 3.1的iPad iOS7正常工作。
dk123

6

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

在这里很好地记录了下来,包括如何将状态栏还原到其iOS7之前的状态。

要安装插件,请运行:

cordova plugin add org.apache.cordova.statusbar

然后将其添加到config.xml

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

您还可以设置默认为黑色的StatusBar颜色:<preference name =“ StatusBarBackgroundColor” value =“#000000” />请参阅:plugins.cordova.io
package

2
对于Cordova 5+,该插件已重命名:cordova插件add cordova-plugin-statusbar
raider33

5

我通过安装org.apache.cordova.statusbar并添加top来解决我的问题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/



1

如果检测到iOS7,我将使用以下代码向主体添加一个类。然后,我对该类进行样式设置20px以在容器顶部添加边距。确保已安装“设备”插件,并且此代码在“ deviceready”事件内。

通过阅读,我听说Phonegap的下一个更新(我相信是3.1)将更好地支持对iOS7状态栏的更改。因此,这可能只是短期解决方案。

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


1

另一种方法是向后兼容。根据制作HTML iOS 7(顶部额外留有20px的边距)以给出full screen外观,并削减的额外边距iOS < 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的用户会发现奇数和


0

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

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

我将等待您的反馈!:)


这段代码看起来非常有用,可以隐藏状态栏并解决问题,昨天我也环顾了一下,发现了一段宁静的代码,该代码本质上重新调整了UIWebView的大小并将其向下移动,我也将其添加为答案:)
Luddig

那很棒。我的代码仅使用一种简单的方法来完成!我们所有人都用不同的方法做同样的事情:)
Ehsan

0

如果我们将相机插件用于图库,状态栏将会返回,因此要解决该问题,请添加此行

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

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

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


0

启动时,在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及更高版本。


0

要使状态栏保持纵向显示而将其隐藏为横向(即全屏显示),请尝试以下操作:

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开发者,我摸索了解决方案的方法)。


0

首先,在您的项目中添加Device插件。插件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");
    }
}

0

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

经过不断的挫折,在Internet上进行了大量搜索,以下是您需要采取的步骤:

  1. 确保您使用状态栏插件
  2. 将此设置添加到您的config.xml中:

<偏好名称=“ StatusBarOverlaysWebView”值=“ false” />

  1. onDeviceReady上使用以下代码

        StatusBar.show();
        StatusBar.overlaysWebView(false);
        StatusBar.backgroundColorByHexString('#209dc2');

适用于iOS和Android。

祝好运!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.