在 iPhone 中的 StatusBar 上添加视图

发布于 2024-09-01 04:22:25 字数 63 浏览 4 评论 0原文

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

Is it possible to add a UIView on the staus bar of size (320 x 20)? I don't want to hide the status bar, I only want to add it on top of the status bar.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

油焖大侠 2024-09-08 04:22:25

您可以通过在现有状态栏上方创建自己的窗口来轻松实现此目的。

只需使用以下 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

您现在可以在应用程序的视图控制器中创建新类的实例并使其可见。

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

请注意使用 - (void)makeKeyAndVisible 或类似方法会弄乱窗口键状态。如果您使主窗口(应用程序代理中的 UIWindow)松散按键状态,则在点击状态栏等时,您将遇到滚动视图滚动到顶部的问题。

You can easily accomplish this by creating your own window above the existing status bar.

Just create a simple subclass of UIWindow with the following override of 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

You can now, for example in a view controller in your application, create an instance of your new class and make it visible.

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

Be aware of messing with the window key status by using - (void)makeKeyAndVisible or similar. If you make your main window (the UIWindow in your Application Delegate) loose key status, you will encounter problems with scrolling scrollviews to top when tapping the status bar etc.

烧了回忆取暖 2024-09-08 04:22:25

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

MTStatusBarOverlay
MTStatusBarOverlay

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

请随意使用它或向我发送 Pull 请求来增强它!

I wrote a static library mimicing Reeders status bar overlay, you can find it here: https://github.com/myell0w/MTStatusBarOverlay

MTStatusBarOverlay
MTStatusBarOverlay

It currently supports iPhone and iPad, default and opaque black status bar styles, rotation, 3 different anymation modes, history-tracking and lots of more goodies!

Feel free to use it or send me a Pull Request to enhance it!

仅此而已 2024-09-08 04:22:25

所有答案看起来都可以工作,但在 iOS6.0 中我遇到了下一个问题:

1/ 旋转看起来很糟糕

2/ 窗口(状态栏是一种窗口)需要 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 上运行良好。

All answers looks like working, but in iOS6.0 I have next problems:

1/ Rotations looks bad

2/ Window (status bar is kind of Window) needed rootViewController

I'm using answer from myell0w, but rotate works not good. I've just remove one extra window and using UIWindow from AppDelegate to implement status bar.
May be this solution is ok only for one UIViewController-app...

Ive implemented by the next way:

1/ In ApplicationDelegate:

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

2/ Create custom UIView and implement all that you need inside:
For an example touchable statusbar:

@interface LoadingStatusBar : UIControl 

And easily create and add to your controller view:

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

3/ Some magic when add your controller view (in initWithFrame:)

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

Your controller view will has 2 views - content view and status bar view. You can show status bar, or hide it when you want.
Frame of content view will be:

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

4/ And one last magic here :)
To detect touches in non touchable area I've used:

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

For now it works fine on iPad/iPhone and all iOS's from 4 to 6.

乖乖兔^ω^ 2024-09-08 04:22:25

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

我不知道怎么做,但我知道这是可行的。名为 Reeder 的 Feed 阅读器应用程序可以做到这一点。

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

屏幕右上角的小图标 替代文字

Just to dismiss the "You cannot do this comments"...

I don't know how but I know it is doable. The Feed reader app called Reeder does that.

As you can see from the screenshot, Reeder puts a small dot on the top right of the screen. When you tap it. The bar will fill the whole statusbar until you tap it again to make it small.

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

西瑶 2024-09-08 04:22:25

首先,非常感谢@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
}

< code>kStatusBarChangedNotification 只是我为了方便参考而使用的常量,您可以简单地将其替换为字符串,或者全局声明该常量。

First of all, a big thank you to @Martin Alléus for providing the code for this implementation.

I'm just posting for a problem that I faced and the solution I used, as I believe others might experience the same issue.

If the App is started while an call is in place, the status bar height will be 40 pixels and this means that the custom status bar will be initialized with that height.
But if the call is ended while you are still in the app, the status bar height will remain still 40 pixels and it will look weird.

So the solution is simple: I've used the Notification center to subscribe to the status bar frame change delegate of the app and adjust the frame:

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

And in the ACStatusBarOverlayWindow we subscribe to the notification:

-(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;
}

and our code to adjust the frame:

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

The kStatusBarChangedNotification is just a constant I've used for easy referrence, you can simply replace it with a string, or declare the constant globally.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文