Строка состояния iOS 7 с Phonegap

91

В iOS 7 приложения Phonegap будут отображаться под строкой состояния. Это может затруднить нажатие на кнопки / меню, размещенные в верхней части экрана.

Есть ли кто-нибудь, кто знает, как исправить эту проблему со строкой состояния на iOS 7 в приложении Phonegap?

Я пытался сместить всю веб-страницу с помощью CSS, но, похоже, это не сработало. Есть ли способ смещения всего UIWebView или просто заставить строку состояния вести себя так, как это было в iOS6?

Благодарность

Luddig
источник
в чем именно заключается "проблема со статусной строкой"? Любой образец кода для воспроизведения?
Raptor
1
@ShivanRaptor В iOS 7 строка состояния теперь является частью представления, поэтому, если у вас есть что-то, что было вверху экрана с предыдущими версиями iOS, теперь оно находится под строкой состояния, а не автоматически перемещается прямо под ней, что может вызвать некоторые проблемы. Я предлагаю создать оболочку для вашего контента и установить верхнее поле 20 пикселей.
Эндрю Лайвли
@AndrewLively - это действительно не работает, когда страница прокручивается, есть ли способ переместить UIWebView?
Luddig

Ответы:

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];
}
Luddig
источник
9
Кто-нибудь еще использует это с плагином In App Browser? Если я сконфигурирую In App Browser как «presentationstyle = fullscreen», после закрытия браузера появится пустое нижнее поле. Похоже, поле имеет ту же высоту, что и панель инструментов InAppBrowser. Установка типа презентации на «лист страницы» исправляет это на iPad, но iPhone, кажется, всегда использует «полноэкранный режим». Есть обходные пути?
Пол
1
Очень признателен за ответ - однако та же проблема относится к браузеру PhoneGap inApp - он также перекрывает строку состояния. Есть идеи для этого?
Майкл
2
Да, мы используем старую версию Cordova (2.3.0), и чтобы исправить это, вам нужно установить webViewBounds.origin.y = 20; в createViewsWithOptions. Также посмотрите, устанавливается ли цвет фона, и поиграйте с ним. Выполните проверку версии для iOS7 и выше, как в этом отличном ответе Людвига Кристофферссона.
hnilsen
3
Кроме того, если вы используете InAppBrowser, представление будет повторно инициализироваться каждый раз, когда вы вернетесь. Поэтому было бы разумно добавить в ваш MainViewController.m флаг, который говорит, что он уже запущен.
hnilsen
14
Поскольку этот код работает в viewWillAppear, вы столкнетесь с проблемами с этим решением, если ваше приложение PhoneGap / Cordova отображает другие собственные представления (например, диалоговое окно захвата камеры) и возвращается в это представление. Исправление для меня заключалось в том, чтобы инициализировать viewBounds как [self.view bounds] 'вместо' [self.webView bounds] '.
Крис Керхер
37

В дополнение к исправлению изменения размера Людвига Кристофферссона я рекомендую изменить цвет строки состояния:

- (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;
}
Alex L
источник
1
Работает
отлично
Идеально - это было лучшее решение для меня.
David Daudelin
Это исправление работает локально после сборки Xcode, но не после сборки телефонного разговора. Любые идеи? У меня есть приложение для iOS, созданное с использованием телефонного разговора 2.9
DemitryT
Это решение работает, но у меня была проблема с полноэкранными видео, и я нашел это другое, и оно устранило
magorich
1
@KirankumarSripati на самом деле моим последним решением было это, надеюсь, это сработает для вас NSInteger screenSize = 0; // Глобальный if ([[[UIDevice currentDevice] systemVersion] floatValue]> = 7) {CGRect viewBounds = [self.webView bounds]; viewBounds.origin.y = 20; если (screenSize == 0) {viewBounds.size.height = viewBounds.size.height - 20; screenSize = viewBounds.size.height; } self.webView.frame = viewBounds; } Я сделал это, потому что мое приложение
меняло
22

пожалуйста, установите этот плагин для телефонной связи: https://build.phonegap.com/plugins/505

И используйте правильную настройку, как показано ниже, для управления наложением веб-просмотра:

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

У меня с Phonegap 3.3.0 все работает.

Более подробная информация на странице проекта Github: https://github.com/phonegap-build/StatusBarPlugin

xdemocle
источник
Большое спасибо за этот ответ !! Пробовал с этим плагином: build.phonegap.com/plugins/715 , проблема в том, что имена совпадают. Но у меня никогда не работает. Большое спасибо!!
Jabel Márquez
Если честно, я не помню, пробовал ли я до этого, упомянутого вами.
xdemocle 05
20

Чтобы скрыть строку состояния, добавьте следующий код в файл MainViewController.mпод функцией-(void)viewDidUnload

- (BOOL)prefersStatusBarHidden
{
    return YES;
}
Markmarijnissen
источник
Это делает свою работу. Он скроет строку состояния, сделав ваше приложение полноэкранным. Я тестировал это только на симуляторе, но сообщу позже, когда запущу сборку на своих iPhone и iPad.
Роб Эванс
У меня работает на iOS на iPad 2
Марк Уильямс
Это отлично работает на iPad Air iOS 7.1.2, и нет необходимости в каких-либо изменениях или плагинах. Отличный ответ, спасибо!
Scriptlabs 06
Это полностью игнорирует все, что Apple говорит о «иммерсивном полноэкранном режиме» в Руководстве по человеческому интерфейсу ... просто потому, что вы используете оболочку поверх iOS, не означает, что вы можете игнорировать шаблоны проектирования ...: /
господи .co.tt
15

Ответ https://stackoverflow.com/a/19249775/1502287 у меня сработал, но мне пришлось немного изменить его, чтобы он работал с плагином камеры (и, возможно, с другими) и метатегом области просмотра с «height = device- height "(если не задавать высоту, то в моем случае клавиатура будет отображаться поверх вида, скрывая некоторые входные данные по пути).

Каждый раз, когда вы открываете вид камеры и возвращаетесь в свое приложение, будет вызываться метод viewWillAppear, и ваше представление будет уменьшаться на 20 пикселей.

Кроме того, device-height для области просмотра будет включать 20 дополнительных пикселей, делая контент прокручиваемым и на 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" />

И теперь все работает хорошо.

Dieppe
источник
Любой метод без JQuery @dieppe
Arjun T Raj
просто добавьте этот код в метод - (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info {} внутри CDVCamera.m, который также решает проблему с камерой. NSLog (@ "ЗАКРЫТАЯ КАМЕРА"); [[UIApplication sharedApplication] setStatusBarHidden: ДА withAnimation: UIStatusBarAnimationNone];
Arjun T Raj
Я не знаю слов, чтобы сказать тебе спасибо! Я боролся с проблемой усадки на 20 пикселей с помощью камеры и до сих пор не мог найти решения ...
Tuks
6

Попробуйте зайти в (app name)-Info.plistфайл приложения в XCode и добавить ключи

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

У меня это работает без проблем.

dk123
источник
Для меня это работает в симуляторе с локальной сборкой, но не в iPad с удаленной сборкой. Использование PG 3.1 для сборки и iOS7 на симуляторе и iPad.
Пер Кестед Аронссон
@PerQuestedAronsson Вы можете попробовать собрать его локально на iPad. Я без проблем работаю с iPad iOS7 с phonegap 3.1.
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" />
track0
источник
Вы также можете установить цвет StatusBar , который по умолчанию черный: <имя предпочтения = значение «StatusBarBackgroundColor» = «# 000000» /> См: plugins.cordova.io/#/package/org.apache.cordova.statusbar
ezzadeen
2
Для Cordova 5+ плагин был переименован: cordova plugin add cordova-plugin-statusbar
raider33 02
5

Решаю свою проблему установкой 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/

Mayconbelfort
источник
1

Я использую следующий фрагмент кода для добавления класса в тело, если обнаружена iOS7. Затем я задаю стиль этому классу, чтобы добавить 20pxполе в верхней части контейнера. Убедитесь, что у вас установлен плагин «device» и что этот код находится внутри события «deviceready».

Читая вокруг, я слышал, что следующее обновление Phonegap (я считаю, 3.1) лучше поддержит изменения в строке состояния iOS7. Так что это может понадобиться как краткосрочное решение.

if(window.device && parseFloat(window.device.version) >= 7){
  document.body.classList.add('fix-status-bar');
}
Райан
источник
1

Ответ Людвига сработал для меня.

Для тех, кто использовал его ответ и теперь хочет изменить цвет белого поля (может показаться тривиальным, но меня озадачили), см. Это:

Как я могу изменить цвет фона UIWebView после сдвига UIWebView вниз, чтобы исправить проблему наложения строки состояния iOS7?

Павел
источник
1

Другой способ - обратная совместимость . Сделайте HTML в соответствии с iOS 7(с дополнительным полем 20 пикселей вверху), чтобы придать такой 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

Напишите следующий код внутри AppDelegate.m в событии didFinishLaunchingWithOptions (точно перед последней строкой кода « return YES; »):

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

Жду ваших отзывов! :)

Эхсан
источник
Этот код отлично работает, чтобы скрыть строку состояния и исправить проблему, вчера я также немного огляделся и нашел кусок кода, который существенно изменил размер UIWebView и переместил его вниз. Я также добавил это в качестве ответа :)
Luddig
Замечательно. Мой код использует только простой и легкий способ сделать это! Все мы делаем одно и то же разными методами :)
Эхсан
0

если мы используем плагин камеры для галереи изображений, строка состояния вернется, поэтому, чтобы исправить эту проблему, добавьте эту строку

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

к

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

функция внутри CVDCamera.m в списке плагинов

Арджун Т Радж
источник
0

Напишите следующий код внутри AppDelegate.m в событии didFinishLaunchingWithOptions при запуске.

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 (чтобы не жестко кодировать значение 20 пикселей) и некоторых заклинаний с моей стороны (я не разработчик iOS, поэтому Я нашел это решение).

matb33
источник
0

Прежде всего, добавьте плагин устройства в свой проект. Идентификатор плагина: 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

После непрекращающегося разочарования и долгого поиска в Интернете вам необходимо предпринять следующие шаги:

  1. Убедитесь, что вы используете плагин строки состояния
  2. Добавьте этот параметр в свой config.xml:

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

  1. Используйте следующий код на onDeviceReady

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

У меня работает на iOS и Android.

Удачи!

Нив Асраф
источник