Запретить запуск строки состояния iOS во время вызова Phonegap UIWebView за кадром

Моя проблема такова: всякий раз, когда пользователь iPhone звонит или использует свой телефон в качестве точки доступа, строка состояния iOS 7 увеличивается, тем самым нажав мое приложение Phonegap UIWebView в нижней части экрана. Увеличенная строка состояния называется "строкой состояния вызова". См. Ниже изображение:

Wonky in-call status bar.

Ответы на переполнение стека Я попытался исправить это:

Iphone- Как изменить размер отображения в строке состояния звонка?

Как строка состояния вызова влияет на размер представления UIViewController? (и как правильно его обрабатывать)

Кроме того, похоже, что в Phonegap нет какого-либо события, которое информирует меня о изменении строки состояния. Прослушивание события "пауза" Phonegap бесполезно, так как 1) он известен своими причудами в iOS и 2) он действительно не охватывает случай горячей точки.

Мои умения Objective-C очень минимальны, и я только прибегаю к задаче такого вопроса после того, как вы разместили необходимые 4 + часы Googling, Stack Overflowing, wailing и т.д.

Боги, принесите мне свою бодрую бодрую ярость.

Ответы

Ответ 1

Придумал следующее решение, основанное на предложениях Jef. Что вы хотите сделать, это следующее:

  • Соблюдайте собственный didChangeStatusBarFrame делегат
  • Получить информацию о размере строки состояния с помощью встроенного statusBarFrame
  • Экспортируйте информацию в свой веб-просмотр, вызывая событие, которое передает его

У меня есть настройка Github repo со всем кодом, который вы найдете в этом ответе.

Уведомление об установке в AppDelegate

// Appdelegate.m
- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame
{
  NSMutableDictionary *statusBarChangeInfo = [[NSMutableDictionary alloc] init];
  [statusBarChangeInfo setObject:@"statusbarchange" 
                     forKey:@"frame"];

  [[NSNotificationCenter defaultCenter] postNotificationName:@"statusbarchange" 
                                        object:self 
                                        userInfo:statusBarChangeInfo];
 }

Сделать доступным селектор statusBarChange

// MainViewController.h
@protocol StatusBarChange <NSObject>
    -(void)onStatusbarChange:(NSNotification*)notification;
@end

Настройка слушателя. Это получает словари origin и size от statusBarFrame всякий раз, когда он изменяется и запускает событие в веб-просмотре, проходящем по этим данным.

// MainViewController.m
- (void)onStatusbarChange:(NSNotification*)notification
{
    // Native code for
    NSMutableDictionary *eventInfo = [self getStatusBarInfo];
    [self notifiy:notification.name withInfo:eventInfo];
}

- (void)notifiy:(NSString*)event withInfo:(NSMutableDictionary*)info
{
    NSString *json = [self toJSON:info];
    NSString *cmd = [NSString stringWithFormat:@"cordova.fireWindowEvent('\%@\', %@)", event, json];
    [self.webView stringByEvaluatingJavaScriptFromString:cmd];
}

- (NSMutableDictionary *)getStatusBarInfo
{
    CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];

    NSMutableDictionary *statusBarInfo = [[NSMutableDictionary alloc] init];
    NSMutableDictionary *size = [[NSMutableDictionary alloc] init];
    NSMutableDictionary *origin = [[NSMutableDictionary alloc] init];

    size[@"height"] = [NSNumber numberWithInteger:((int) statusBarFrame.size.height)];
    size[@"width"] = [NSNumber numberWithInteger:((int) statusBarFrame.size.width)];

    origin[@"x"] = [NSNumber numberWithInteger:((int) statusBarFrame.origin.x)];
    origin[@"y"] = [NSNumber numberWithInteger:((int) statusBarFrame.origin.y)];

    statusBarInfo[@"size"] = size;
    statusBarInfo[@"origin"] = origin;

    return statusBarInfo;
}

- (NSString *) toJSON:(NSDictionary *)dictionary {
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
    return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Все это позволяет прослушивать событие window.statusbarchange, например. например:

// www/js/index.js
window.addEventListener('statusbarchange', function(e){
  // Use e.size.height to adapt to the changing status bar      

}, false)

Ответ 2

Я бы сказал, что это всегда происходит, когда вы возвращаетесь с фона, нет?

В других словах возможно ли расширение бара без вашего приложения, которое, по крайней мере, кратковременно переводится на задний план с помощью входящего вызова и т.д.?

Если вы уверены, что можете запросить высоту строки состояния в своих делегатах - (void) будет (илиDid) возобновляться и корректироваться соответственно?

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

Редактируйте здесь, вот они, выберите одно из этих уведомлений, чтобы наблюдать..

UIApplicationWillChangeStatusBarFrameNotification

UIApplicationDidChangeStatusBarFrameNotification

Или реализовать один из этих обратных вызовов в своем делетете

-application:willChangeStatusBarFrame:

-application:didChangeStatusBarFrame: