2013-09-25 1 views
36

Проблемы я столкнулся это:Перемещения строки состояния в прошивке 7

Я хочу реализовать IOS 7 приложение с хорошим дизайном и влево/вправо в меню, которое появляется после того, как основной вид самого одушевленный вправо /оставил. Я делаю это с кодом [UIView animateWithDuration...], но это не очень важно. То, что я хочу, чтобы достичь такой же эффект почтового ящика IOS 7 приложение имеет: переместить строку состояния в сторону (вправо/влево) с основным видом

изображения для лучшего объяснения:

Mailbox app with status bar moved to the side

Что я нашел, это только статья this, посвященная проблеме, с некоторым рабочим кодом с использованием Private API, который я бы не хотел использовать, так как я хочу, чтобы приложение было принято в App Store.

Я хотел бы добиться такого же эффекта («юридически»). Кто-нибудь знает, как это сделать?

Спасибо!

+0

Почтовый ящик, как представляется, не использует стандартную строку состояния. Они приклеивают дополнительный текст там, поэтому я предполагаю, что они используют что-то вроде https://github.com/myell0w/MTStatusBarOverlay, но обновлены для iOS 7. –

+0

Создайте контроллер контейнера и добавьте свое меню и главное представление как childViewControllers. Затем вы можете установить строку состояния, скрытую в диспетчере меню, и она сохранит строку состояния другого контроллера режима просмотра, не используя скриншоты (которые, на мой взгляд, кажутся невосприимчивыми). – user

+0

@user у вас был пример проекта? Если да, можете ли вы поделиться этим? –

ответ

47

Суть его заключается в использовании этого метода, введенный в прошивке 7:

https://developer.apple.com/documentation/uikit/uiscreen/1617814-snapshotview:

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

Я опубликовал доказательство концепции здесь: https://github.com/simonholroyd/StatusBarTest

ПРИМЕЧАНИЕ Я не представленный код, который делает это через процесс обзора Apple, но это не частный метод API.

+0

Это выглядит интересно, я рассмотрю его и расскажу о своих выводах! – Gyfis

+5

Что-то еще следует отметить, если вы перейдете к этой функции: приложение Mailbox имеет ошибку, когда при многозадачности отображаемый снимок экрана не подавляет строку состояния. Поэтому, если вы выходите из приложения с открытым меню слева, а затем многозадачно, вы увидите дубликаты статусных баров в режиме многозадачности. –

+0

Это на самом деле очень приятно знать! Они не боги :) Спасибо! – Gyfis

-3

По моему опыту, рецензенты App Store, как правило, не заботятся об использовании частного API, особенно это просто и безвредно. Для задания вы можете получить указатель зрения в строке состояния приложения через несколько методов, которые вы можете найти в IOS полных заголовков, как https://github.com/nst/iOS-Runtime-Headers

+7

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

7

Итак, после первоначального нажатия г-на Саймона Холройда и некоторых поисков я нашел решение о том, как достичь этой «эффекта». Это код:

statusbarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)]; 

EDIT: господин pcholberg правильно указал, что прежний код не работает на реальном устройстве, только на IOS Simulator, так что я редактировал его рекомендации

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) 
{ 
    UIView *screenShot = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO]; 
    [statusbarView addSubview:screenShot]; 
    [statusbarView setClipsToBounds:YES]; 
    [self.view addSubview:statusbarView]; 

    [self setPrefersStatusBarHidden:YES]; 
    [self prefersStatusBarHidden]; 
    [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)]; 
} 

...

- (BOOL)prefersStatusBarHidden 
{ 
    return prefersStatusBarHidden; 
} 

...


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

Вторая часть добавляет снимок UIView к моей ViewController-х UIView

И третья часть устанавливает для моего bool для строки состояния значение YES (для более простого использования в методе выше) и вызывает методы для ее перерисовки

В этом случае UIView устанавливает как не-функциональную строку состояния на своем месте и скрывает оригинал, поэтому нет двойной рендеринга. Тогда я могу использовать это представление в моем [UIView animateWithDuration... методы

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

[statusbarView removeFromSuperview]; 

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) 
{ 

    [self setPrefersStatusBarHidden:NO]; 
    [self prefersStatusBarHidden]; 
    [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)]; 

} 

и вуаля! Это работает как описанный эффект в моем вопросе.

Надеюсь, это поможет кому-то!

+1

Не отображать snapshotView ([[UIScreen mainScreen] snapshotViewAfterScreenUpdates: NO]) в изображение, моментальный снимок будет отображаться без текста в строке состояния на реальном устройстве. Просто добавьте этот shanpshot как subview. – pcholberg

+0

Вы абсолютно правы! Это как-то работает на симуляторе, однако не на самом устройстве. Но я не смог добавить снимок в качестве подсмотра и переместить его потом, так как он, кажется, изменился через некоторое время ... – Gyfis

+1

Какова цель '[self prefersStatusBarHidden];' в вашем коде, поскольку вы ничего не делаете с возвращаемым значением? И почему вы должны делать '[self performSelector: @selector (setNeedsStatusBarAppearanceUpdate)]; вместо того, чтобы просто' [self setNeedsStatusBarAppearanceUpdate] '? Если ваш код не работает без этих строк, я бы не захотел использовать его в приложении, так как он, вероятно, внезапно перестанет работать с новой версией iOS. – MusiGenesis

3

Я только что создал BSPanViewController, что делает его чрезвычайно простым для достижения этого эффекта. Элемент управления и инструкции по его использованию могут быть found on GitHub.

Реализация такая же, как и у explained by Simon Holroyd.

+0

поддерживает ли этот режим UITableViewCell? –

7

Я использую этот метод для перемещения statuebar со слайдером, в приложении есть два окна, одно нормальное окно, другое statuBarWindow, я получаю statuBarView, который superView является statuBarWindows и перемещает его с помощью слайдера.

- (UIView *)statuBarView 
{ 
    NSString *key = [[NSString alloc] initWithData:[NSData dataWithBytes:(unsigned char []){0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x61, 0x72} length:9] encoding:NSASCIIStringEncoding]; 
    id object = [UIApplication sharedApplication]; 
    UIView *statusBar = nil; 
    if ([object respondsToSelector:NSSelectorFromString(key)]) { 
     statusBar = [object valueForKey:key]; 
    } 
    return statusBar; 
} 
+0

Это довольно интересно .. считается ли это использование частных API яблок? Кроме того, почему вы используете dataWithBytes вместо того, чтобы просто @ "statusBar", что то, что превращается в .. это то, чтобы избежать обнаружения в некотором роде? (похоже, что они проверили бы эту простую работу вокруг.) – Cypher

+0

Прекрасно обфускация;) – DrMickeyLauer

Смежные вопросы