Рядок стану iOS 7 із Phonegap


91

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

Хтось знає спосіб виправити цю проблему з рядком стану на iOS 7 у програмі Phonegap?

Я намагався компенсувати всю веб-сторінку за допомогою CSS, але, здається, це не працює. Чи є спосіб подолати компенсацію всього UIWebView або просто зробити так, щоб рядок стану поводився так, як у iOS6?

Дякую


в чому саме полягає "проблема в рядку стану"? Будь-який зразок коду для відтворення?
Raptor

1
@ShivanRaptor У iOS 7 рядок стану тепер є частиною подання, тому якщо у вас є речі, які знаходились у верхній частині екрана з попередніми версіями iOS, вони тепер знаходяться під рядком стану, а не автоматично натискаються прямо під ним, що може спричинити деякі проблеми. Я пропоную створити обгортку для вашого вмісту та встановити верхнє поле 20px.
Ендрю Лайвли

@AndrewLively - Це насправді не працює, коли сторінка прокручується, чи є спосіб перенести UIWebView?
Люддіг

Відповіді:


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 як "презентація = повноекранний режим", після закриття браузера з'явиться пусте нижнє поле. Схоже, поля мають таку саму висоту, що і панель інструментів InAppBrowser. Встановлення типу презентації "сторінка" це виправляє на iPad, але iPhone, здається, завжди використовує "повноекранний". Будь-які обхідні шляхи?
Павло,

1
Дуже вдячний за відповідь - проте те саме питання стосується браузера PhoneGap inApp - він також накладає рядок стану. Будь-які ідеї для цього?
Michael

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]'.
Chris Karcher,

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

1
Відмінно
працюю

Ідеально - це було найкраще рішення для мене.
Девід Доделін,

Це виправлення працює локально після побудови Xcode, але не після того, як я буду фонепап-побудову. Будь-які ідеї? У мене є додаток для iOS, побудований з фонегапом 2.9
DemitryT

Це рішення працює, але у мене була проблема з повноекранними відео, і я знайшов це інше, і це вирішило
magorich

1
@KirankumarSripati насправді моїм останнім рішенням було це, сподіваюсь thiw працює для вас NSInteger screenSize = 0; // Глобальний if ([[[UIDevice currentDevice] systemVersion] floatValue]> = 7) {CGRect viewBounds = [межі self.webView]; viewBounds.origin.y = 20; if (screenSize == 0) {viewBounds.size.height = viewBounds.size.height - 20; screenSize = viewBounds.size.height; } self.webView.frame = viewBounds; } Я зробив це, оскільки мій додаток
змінював

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 , проблема в тому, що імена однакові. Але ніколи не працює для мене. Дуже дякую!!
Jabel Márquez

Чесно кажучи, я не пам’ятаю, чи пробував я до цього, згаданого вами.
xdemocle

20

Щоб приховати рядок стану, додайте наступний код у файл MainViewController.mпід функцією-(void)viewDidUnload

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Це робить роботу. Він приховає рядок стану, завдяки чому програма стане повноекранною. Я протестував це лише на симуляторі, але повідомлю про це пізніше, коли буду виконувати збірку на своїх iPhone та iPad.
Роб Еванс

Працює у мене на iOS на iPad 2
Марк Вільямс,

Це чудово працює на iPad Air iOS 7.1.2, і немає потреби в будь-яких змінах або плагінах. Чудова відповідь, дякую!
Scriptlabs

Це повністю ігнорує все, що Apple говорить про `` іммерсивний повноекранний режим '' в Інструкціях щодо людського інтерфейсу ... те, що ви використовуєте обгортку поверх iOS, не означає, що ви можете ігнорувати шаблони дизайну ...: /
jesses .co.tt

15

Відповідь https://stackoverflow.com/a/19249775/1502287 у мене спрацювала, але мені довелося трохи її змінити, щоб вона працювала з плагіном камери (і, можливо, іншими) та мета-тегом області перегляду з "висота = пристрій- висота "(якщо не встановити частину висоти, в моєму випадку клавіатура відображатиметься над видом, приховуючи деякі входи по дорозі).

Кожного разу, коли ви відкривали вигляд камери і поверталися до своєї програми, викликався метод viewWillAppear, і ваш вигляд зменшувався на 20 пікселів.

Крім того, висота пристрою для області перегляду включала б 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];
}

Тепер для проблеми з вікном перегляду, у вашому пристрої вже прослуховувач подій додайте це (за допомогою 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

просто додайте цей код до - (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info {} методу всередині CDVCamera.m, який також вирішує проблему з камерою. NSLog (@ "ЗАКРИТА КАМЕРА"); [[UIApplication sharedApplication] setStatusBarHidden: ТАК зAnimation: UIStatusBarAnimationNone];
Arjun T Raj

Чоловіче, я не знаю слів, щоб сказати спасибі! Я боровся з проблемою усадки 20px з камерою, і дотепер не міг знайти рішення ...
tuks

6

Спробуйте зайти у (app name)-Info.plistфайл програми в XCode і додати ключі

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

Це працює для мене без проблем.


Для мене це працює в симуляторі з локальною збіркою, але не в iPad з віддаленою збіркою. Використання PG 3.1 для збірки та iOS7 на симуляторі та iPad.
Per Quested Aronsson

@PerQuestedAronsson Ви можете спробувати побудувати його локально на iPad. Я без проблем працюю з iPad iOS7 з фонегапом 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" />

Ви також можете встановити колір StatusBar , який по замовчуванням чорний: <ім'я переваги = значення «StatusBarBackgroundColor» = «# 000000» /> Див: plugins.cordova.io/#/package/org.apache.cordova.statusbar
ezzadeen

2
Для Cordova 5+ плагін перейменовано: плагін cordova додайте cordova-plugin-statusbar
raider33

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/



1

Я використовую наступний фрагмент коду, щоб додати клас до основного тіла, якщо виявлено iOS7. Потім я стилюю цей клас, щоб додати a20px поле вгорі мого контейнера. Переконайтесь, що у вас встановлений плагін "пристрій", і що цей код знаходиться всередині події "девайс".

Почитавши, я чув, що наступне оновлення 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 (щоб не кодувати значення 20px) та деякі заклинання з мого боку (я не розробник iOS, тому Я докопався до цього рішення).


0

Перш за все, додайте плагін Device до проекту. Ідентифікатор плагіна: 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.

Удачі!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.