在iPhone上添加状态栏的视图

问题描述:

是否可以在尺寸为(320 x 20)的状态栏上添加UIView?我不想隐藏状态栏,我只想将它添加到状态栏的顶部。在iPhone上添加状态栏的视图

+4

只是一个评论,如果你有兴趣发布到苹果的应用商店 - [Reeder应用程序被拒绝](http://twitter.com/#!/ reederapp/status/125598161849942016)因为这个功能。 – phi 2012-01-20 08:42:15

+1

@Irene - 我为我的[Python for iOS](http://pythonforios.com)应用程序编写了自定义状态栏视图,并且最近更新了App Store的更新。尽管Reeder应用程序被拒绝,但苹果政策可能已经改变。 – chown 2012-10-22 19:09:21

+0

使用此功能的Appstore中的很多应用程序 – 2012-11-20 14:41:22

您可以轻松地通过创建现有状态栏上您自己的窗口做到这一点。

刚刚创建的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

请注意,将常规状态栏(灰色)和不透明黑色叠加在一起很简单。如果你的应用程序有一个半透明的酒吧,你需要隐藏它,并将自己的视图放置在它的位置(因为将半透明的酒吧放在原来的顶部只会让一团糟;)) – alleus 2010-05-14 12:48:15

+0

绝对辉煌。 – 2010-05-14 18:58:51

+0

该代码是否缺少“返回自我”?在那里的功能结束? – 2012-05-16 17:14:04

刚刚驳回“你不能做到这一点的意见” ......

我不知道怎样,但我知道它是可行的。 Feed阅读器应用程序称为Reeder。

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

A small icon on the top right of the screenalt text

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

MTStatusBarOverlayMTStatusBarOverlay

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

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

+0

辉煌,谢谢! – conorgriffin 2011-02-18 13:49:26

+0

如何在我的应用程序中没有状态栏的情况下使用此功能。 – 2011-06-29 10:45:15

+5

坏消息,苹果公司开始拒绝使用MTStatusBarOverlay或类似的解决方案,“在原生状态栏顶部显示自定义状态栏叠加层”。显然它违反了HIG:( – 2012-04-02 11:37:47

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

所有答案看起来像工作,但在iOS6.0我未来的问题:

1 /轮换不妙

2 /窗口(状态栏样窗口)需要RootViewController的

我使用myell0w的回答,但旋转工作不好。我刚刚删除了一个额外的窗口,并使用AppDelegate的UIWindow来实现状态栏。 可能是这样的解决方案是只为一个UIViewController中,应用确定...

伊夫被下一个方式来实现:

1 /在ApplicationDelegate:

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

2 /创建自定义的UIView和实施所有你需要的内部: 举一个例子可触摸的状态栏:

@interface LoadingStatusBar : UIControl 

而轻松地添加到您的CONTRO米勒的观点:

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