3

Things 3 Screenshot

In Things 3, the status bar text (wireless signal, time, battery, etc.) in the iOS app is a medium-gray color. Normally you can only have black or white text in the status bar.

How are they doing this?

My first guess is they have a semi-transparent white UIView covering the status bar, but I'm unsure how they pulled that off. I'd love to know how to do this in Swift.

Clifton Labrum
  • 13,053
  • 9
  • 65
  • 128

2 Answers2

4

Here's some sample code in Swift that seems to mimic the Things 3 status bar effect pretty closely. In essence you're creating another window to place directly over the status bar that will mute the color slightly.

Important things to note in this example:

  • We assign the new UIWindow to a property, otherwise it will be released as soon as we leave the scope.
  • We set the windowLevel to UIWindowLevelStatusBar
  • We set isHidden to false instead of calling makeKeyAndVisible, since we still want the normal window to be the key window

AppDelegate.swift:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var overlayWindow = UIWindow()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        overlayWindow.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 20)
        overlayWindow.windowLevel = UIWindowLevelStatusBar
        overlayWindow.backgroundColor = UIColor(white: 1, alpha: 0.4)
        overlayWindow.rootViewController = UIViewController()
        overlayWindow.isHidden = false

        return true
    }
}
mclaughj
  • 12,645
  • 4
  • 31
  • 37
  • This works great. Thank you! The only slight difference I see is that my battery icon is green, whereas Things managed to have a dark battery icon. I wonder how they pulled that off. – Clifton Labrum May 30 '17 at 20:35
  • 1
    @CliftonLabrum The battery icon should only be green if you're plugged in to power, which also happens in Things implementation. – mclaughj May 30 '17 at 21:23
  • It looks like this doesn't handle orientation changes. Would I just have to listen for orientation change and then re-draw it? – Clifton Labrum May 30 '17 at 22:02
1

I expect they do it just as you say by adding a UIWindow over the status bar. Here is sample code that does it (in Objective-C.)

http://www.b2cloud.com.au/tutorial/multiple-uiwindows/

UIWindow* topWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[topWindow setWindowLevel:UIWindowLevelAlert];

CGFloat statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;

UIViewController* viewController = [[ViewController alloc] init];
UIView* overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -statusBarHeight, viewController.view.frame.size.width, statusBarHeight - 1)];
[overlay setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[overlay setBackgroundColor:[UIColor colorWithRed:1 green:0 blue:0 alpha:0.5]];
[viewController.view addSubview:overlay];
[topWindow setRootViewController:viewController];

[topWindow setHidden:NO];
[topWindow setUserInteractionEnabled:NO];

[viewController release];
viewController = nil;

[overlay release];
overlay = nil;
Daniel T.
  • 32,821
  • 6
  • 50
  • 72