2010-05-14 108 views
61

是否可以在尺寸爲(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

回答

85

您可以輕鬆地通過創建現有狀態欄上您自己的窗口做到這一點。

剛剛創建的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

3

剛剛駁回「你不能做到這一點的意見」 ......

我不知道怎樣,但我知道它是可行的。 Feed閱讀器應用程序稱爲Reeder。

從屏幕截圖中可以看到,Reeder在屏幕的右上角放了一個小點。當你點擊它。該條將填充整個狀態欄,直到再次點擊它使其變小。

A small icon on the top right of the screenalt text

58

我寫了一個模擬Reeders狀態欄覆蓋的靜態庫,可以在這裏找到:https://github.com/myell0w/MTStatusBarOverlay

MTStatusBarOverlay MTStatusBarOverlay

它目前支持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

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只是一個常用於簡單引用的常量,您可以簡單地用一個字符串替換它,或者全局地聲明常量。

4

所有答案看起來像工作,但在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.