Добавление представления на StatusBar в iPhone - PullRequest
62 голосов
/ 14 мая 2010

Можно ли добавить UIView на панель состояния размером (320 x 20)? Я не хочу скрывать строку состояния, я хочу добавить ее только поверх строки состояния.

Ответы [ 5 ]

87 голосов
/ 14 мая 2010

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

Просто создайте простой подкласс UIWindow со следующим переопределением initWithFrame:

@interface ACStatusBarOverlayWindow : UIWindow {
}
@end

@implementation ACStatusBarOverlayWindow
- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // Place the window on the correct level and position
        self.windowLevel = UIWindowLevelStatusBar+1.0f;
        self.frame = [[UIApplication sharedApplication] statusBarFrame];

        // Create an image view with an image to make it look like a status bar.
        UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.frame];
        backgroundImageView.image = [UIImage imageNamed:@"statusBarBackground.png"];
        [self addSubview:backgroundImageView];
        [backgroundImageView release];

        // TODO: Insert subviews (labels, imageViews, etc...)
    }
    return self;
}
@end

Теперь вы можете, например, в контроллере представления в вашем приложении создать экземпляр вашего нового класса и сделать его видимым.

overlayWindow = [[ACStatusBarOverlayWindow alloc] initWithFrame:CGRectZero];
overlayWindow.hidden = NO;

Имейте в виду, что можно вмешиваться в состояние ключа окна, используя - (void)makeKeyAndVisible или аналогичный. Если вы потеряете статус главного окна (UIWindow в вашем делегате приложения), вы столкнетесь с проблемами при прокрутке прокручиваемых обзоров вверх при нажатии на строку состояния и т. Д.

58 голосов
/ 11 декабря 2010

Я написал статическую библиотеку, имитирующую наложение строки состояния Reeders, вы можете найти ее здесь: https://github.com/myell0w/MTStatusBarOverlay

MTStatusBarOverlay MTStatusBarOverlay

В настоящее время он поддерживает iPhone и iPad, стандартные и непрозрачные стили черной строки состояния, вращение, 3 различных режима анмации, отслеживание истории и множество других полезностей!

Не стесняйтесь использовать его или отправьте мне запрос на повышение, чтобы улучшить его!

4 голосов
/ 20 ноября 2012

Все ответы выглядят как рабочие, но в iOS6.0 у меня следующие проблемы:

1 / Поворот выглядит плохо

2 / Window (строка состояния - это тип Window), необходимый rootViewController

Я использую ответ от myell0w , но вращение работает не очень хорошо. Я только что удалил одно дополнительное окно и использовал UIWindow из AppDelegate для реализации строки состояния. Может быть, это решение подходит только для одного приложения UIViewController ...

Я реализован следующим образом:

1 / В заявке на делегирование:

self.window.windowLevel = UIWindowLevelStatusBar + 1;
self.window.backgroundColor = [UIColor clearColor];
self.window.rootViewController = _journalController;

2 / Создайте пользовательский UIView и внедрите все, что вам нужно внутри: Для примера сенсорной строки состояния:

@interface LoadingStatusBar : UIControl 

И легко создавать и добавлять в ваш контроллер вид:

_loadingBar = [[LoadingStatusBar alloc] initWithFrame:topFrame];
[self addSubview:_loadingBar];

3 / Немного магии при добавлении представления вашего контроллера (в initWithFrame:)

    CGRect mainFrame = self.bounds;
    mainFrame.origin.y = 20;
    self.bounds = mainFrame;

Ваш вид контроллера будет иметь 2 вида - просмотр содержимого и просмотр строки состояния. Вы можете показать строку состояния или скрыть ее, когда хотите. Кадр просмотра контента будет:

_contentView.frame = CGRectMake(0, 20, self.bounds.size.width, self.bounds.size.height);

4 / И еще одно волшебство здесь :) Для обнаружения прикосновений в недоступном для прикосновения месте я использовал:

-(id)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (point.y < 20) return _loadingBar;
    return [super hitTest:point withEvent:event];
}

На данный момент он отлично работает на iPad / iPhone и всех iOS с 4 до 6.

3 голосов
/ 14 мая 2010

Просто чтобы отклонить "Вы не можете делать это комментарии" ...

Я не знаю как, но я знаю, что это выполнимо. Приложение Feed Reader под названием Reeder делает это.

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

A small icon on the top right of the screen alt text

1 голос
/ 24 октября 2012

Прежде всего, большое спасибо @Martin Alléus за предоставленный код для этой реализации.

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

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

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

- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame {
    //an in call toggle was done    
    //fire notification
    [[NSNotificationCenter defaultCenter] postNotificationName:kStatusBarChangedNotification object:[NSValue valueWithCGRect:oldStatusBarFrame]];
}

И в ACStatusBarOverlayWindow мы подписываемся на уведомление:

-(id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame]))
    {
        // Place the window on the correct level & position
        self.windowLevel = UIWindowLevelStatusBar + 1.0f;
        self.frame = [UIApplication sharedApplication].statusBarFrame;
        self.backgroundColor = [UIColor blackColor];

        //add notification observer for in call status bar toggling
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarChanged:) name:kStatusBarChangedNotification object:nil];
    }
    return self;
}

и наш код для настройки кадра:

- (void)statusBarChanged:(NSNotification*)notification {
    //adjust frame...    
    self.frame = [UIApplication sharedApplication].statusBarFrame;
    //you should adjust also the other controls you added here
}

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

...