web-dev-qa-db-ja.com

iPhoneのStatusBarにビューを追加する

サイズ(320 x 20)のステータスバーにUIViewを追加することはできますか?ステータスバーを非表示にするのではなく、ステータスバーの上に追加するだけです。

62
Biranchi

これは、既存のステータスバーの上に独自のウィンドウを作成することで簡単に実現できます。

次の_initWithFrame:_をオーバーライドして、UIWindowの単純なサブクラスを作成するだけです

_@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
_

これで、たとえばアプリケーションのView Controllerで、新しいクラスのインスタンスを作成して表示できるようになりました。

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

- (void)makeKeyAndVisibleなどを使用して、ウィンドウキーのステータスを変更することに注意してください。メインウィンドウ(アプリケーションデリゲートのUIWindow)のキーステータスを緩めると、ステータスバーなどをタップするときにスクロールビューを上にスクロールするときに問題が発生します。

87
alleus

Reedersステータスバーオーバーレイを模倣した静的ライブラリを作成しました。ここで見つけることができます。 https://github.com/myell0w/MTStatusBarOverlay

MTStatusBarOverlayMTStatusBarOverlay

現在、iPhoneとiPad、デフォルトの不透明な黒のステータスバースタイル、回転、3つの異なるアニメーションモード、履歴追跡、その他多くの機能をサポートしています!

気軽に使用するか、プルリクエストを送信して強化してください!

58
myell0w

すべての答えは機能しているように見えますが、iOS6.0では次の問題があります:

1 /回転が悪く見える

2 /ウィンドウ(ステータスバーはウィンドウの一種)が必要rootViewController

myell0wからの回答を使用していますが、rotateは良くありません。余分なウィンドウを1つ削除し、AppDelegateからUIWindowを使用してステータスバーを実装しました。このソリューションは、1つのUIViewController-appに対してのみOKかもしれません...

次の方法で実装しました:

1/ApplicationDelegateで:

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および4〜6のすべてのiOSで正常に動作します。

4
Sergey Kopanev

「あなたはこのコメントをすることはできません」を却下するために...

方法はわかりませんが、実行可能であることは知っています。 Reederと呼ばれるフィードリーダーアプリがそれを行います。

スクリーンショットからわかるように、Reederは画面の右上に小さなドットを配置します。タップすると。もう一度タップして小さくするまで、バーはステータスバー全体に表示されます。

A small icon on the top right of the screenalt text

3
texmex5

まず、この実装のコードを提供してくれた@MartinAllé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は、簡単に参照できるように使用した定数です。単純に文字列に置き換えるか、定数をグローバルに宣言できます。

1
Lefteris