Правильный способ установки цвета текста строки состояния подсветки в iOS 7 на основе разных ViewControllers

Мне нужно, чтобы определенный ViewController, встроенный в UINavigationController, имел цвет текста строки состояния (но другой ViewController, чтобы вести себя по-другому). Я знаю как минимум 3 метода, ни один из которых, однако, не работает в моем случае.

  • Как изменить цвет текста строки состояния в iOS 7, метод в первую очередь:

    • Установите UIViewControllerBasedStatusBarAppearance на YES в plist
    • В viewDidLoad сделать a [self setNeedsStatusBarAppearanceUpdate];
    • Добавьте следующий метод:

      - (UIStatusBarStyle)preferredStatusBarStyle{ 
            return UIStatusBarStyleLightContent; 
        }
      

    Запуск на iOS 7.0.3, этот метод не работает для меня, так как даже после того, как я выполнил все 3 шага правильно, preferredStatusBarStyle никогда не вызывается.

  • UIStatusBarStyle PreferredStatusBarStyle не работает на iOS 7, метод в первую очередь:

    Настройка navigationBar s barStyle на UIBarStyleBlackTranslucent даст белый текст строки состояния (т.е. UIStatusBarStyleLightContent), а UIBarStyleDefault предоставит черный текст строки состояния (т.е. UIStatusBarStyleDefault).

    Этот метод работает честно и квадратно на iPhone, но не на iPad.

  • Установка UIViewControllerBasedStatusBarAppearance в NO в plist и использование

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    

    Это явно не применяется в этом случае, так как мне нужно указывать только разные цвета строки состояния для двух из ViewController s.

Спасибо за помощь!

Ответы

Ответ 1

Для людей, имеющих эту проблему с UINavigationController, я могу рекомендовать создание пользовательского UINavigationController и реализацию preferredStatusBarStyle на нем следующим образом:

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return [self.topViewController preferredStatusBarStyle];
}

Таким образом стиль статусной панели будет соответствовать типу контроллера верхнего уровня. Теперь вы можете реализовать контроллер вида preferredStatusBarStyle в любом случае.

Ответ 2

Чтобы установить UIStatusBarStyle индивидуально для каждого стека UIViewController on UINavigationController, вы должны сначала подклассифицировать ваш метод UINavigationController и переопределить childViewControllerForStatusBarStyle.

В подклассе UINavigationController добавьте:

-(UIViewController *)childViewControllerForStatusBarStyle {
     return self.visibleViewController;
}

чем вы можете установить UIStatusBarStyle на все, что хотите, в каждом UIViewController, используя метод preferredStatusBarStyle. Например:

-(UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleLightContent;
}

Ответ 3

Здесь улучшается Groot answer, в виде простой категории для UINavigationController, без необходимости подкласса UINavigationController.

Swift

extension UINavigationController {
    override public func preferredStatusBarStyle() -> UIStatusBarStyle {
        return self.topViewController?.preferredStatusBarStyle() ?? .Default
    }
}

Objective-C

@implementation UINavigationController (StatusBarStyle)

- (UIStatusBarStyle)preferredStatusBarStyle 
{
    return [self.topViewController preferredStatusBarStyle];
}

@end

Ответ 4

Я использовал первый метод, о котором вы упомянули, я также обнаружил там свою ошибку, когда вы использовали UINavigationController, он никогда не передаст вызов preferredStatusBarStyle на него дочерние контроллеры. То, что я сделал, - это подкласс UINavigationController и переопределить метод preferredStatusBarStyle следующим образом:

@implementation GLBaseNavigationController

- (UIStatusBarStyle)preferredStatusBarStyle
{
    UIViewController *lastViewController = [self.viewControllers lastObject];
    if ([lastViewController respondsToSelector:@selector(preferredStatusBarStyle)]) {
        return [lastViewController preferredStatusBarStyle];
    } else if ([super respondsToSelector:@selector(preferredStatusBarStyle)]) {
        return [super preferredStatusBarStyle];
    }
    return UIStatusBarStyleDefault;
}

Тогда, когда мне нужен контроллер навигации, я использую GLBaseNavigationController вместо UINavigationController. Для раскадровки вам необходимо также указать класс контроллера навигации для вашего подкласса.

Ответ 5

Для вашего первого решения я не думаю, что вы можете изменить строку состояния в viewDidLoad. Если у вас есть два ViewControllers, уложенных друг на друга, и каждый из них переключает строку состояния по-разному, этот метод будет вызываться только один раз для каждого. Вы действительно хотите изменить строку состояния в viewWillAppear, чтобы она вызывалась каждый раз, когда страница отображается. Я также не думаю, что вы можете положиться на preferredStatusBarStyle, так как я также не уверен, как часто/когда это вызвано. Вот как вы это делаете:

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];
}

Ответ 6

В настоящее время вы можете делать только светлые и темные. Чтобы изменить свет, сделайте.

  • Установите UIViewControllerBasedStatusBarAppearance в YES в файле .plist.

  • В методе viewDidLoad выполните [self setNeedsStatusBarAppearanceUpdate];

  • Добавьте этот метод:

-(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; }

Чтобы изменить его на темноту, измените значение UIStatusBarStyleLightContent на UIStatusBarStyleDefault

Ответ 7

В вашем методе AppDelegate didFinishLaunch задайте стиль строки состояния по умолчанию, скажем:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault
                                                animated:YES];       
    return YES;
}

Затем в ваших двух контроллерах представления, где вы хотите изменить строку состояния, переопределите следующие методы:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated]        

    // Here change status bar color
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent
                                                animated:YES];       

}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear]                

    // Here bring back to color, that we set in AppDelegate
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault
                                                animated:YES];       
}