在iPhone中的StatusBar上添加视图

时间:2010-05-14 11:24:47

标签: iphone uikit uiapplication

是否可以在大小(320 x 20)的状态栏上添加UIView?我不想隐藏状态栏,我只想将其添加到状态栏的顶部。

5 个答案:

答案 0 :(得分:87)

您可以通过在现有状态栏上方创建自己的窗口轻松完成此操作。

只需使用以下覆盖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)松开键状态,则在点击状态栏等时会将滚动视图滚动到顶部时遇到问题。

答案 1 :(得分:58)

我写了一个模拟Reeders状态栏覆盖的静态库,你可以在这里找到它:https://github.com/myell0w/MTStatusBarOverlay

MTStatusBarOverlay MTStatusBarOverlay

它目前支持iPhone和iPad,默认和不透明的黑色状态栏样式,旋转,3种不同的任意模式,历史跟踪和更多好东西!

随意使用它或向我发送拉动请求以增强它!

答案 2 :(得分:4)

所有答案看起来都有效,但在iOS6.0中我有下一个问题:

1 /轮换看起来很糟糕

2 / Window(状态栏是一种Window)需要rootViewController

我正在使用 myell0w 的回答,但旋转效果并不好。我只是删除了一个额外的窗口并使用AppDelegate中的UIWindow来实现状态栏。 可能这个解决方案只适用于一个UIViewController-app ...

我已经通过下一个方式实施了:

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和所有iOS的4到6个。

答案 3 :(得分:3)

只是为了驳回“你不能做这个评论”......

我不知道怎么做但我知道这是可行的。名为Reeder的Feed阅读器应用就是这样做的。

从屏幕截图中可以看出,Reeder在屏幕的右上角放了一个小点。当你点击它。该栏将填充整个状态栏,直到您再次点击它以使其变小。

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

答案 4 :(得分:1)

首先,非常感谢@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只是我用来简单引用的常量,你可以简单地用字符串替换它,或者全局声明常量。