Detecting if user has in call status bar

in-call, ios, statusbar

Solution

`UIApplicationDelegate` has these two methods.

// ObjC
- (void)application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame;   // in screen coordinates
- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame;

// Swift
func application(_ application: UIApplication, willChangeStatusBarFrame newStatusBarFrame: CGRect)
func application(_ application: UIApplication, didChangeStatusBarFrame oldStatusBarFrame: CGRect)

And there are `Notifications` too.

//ObjC
UIApplicationWillChangeStatusBarFrameNotification
UIApplicationDidChangeStatusBarFrameNotification

// Swift
Notification.Name.UIApplicationWillChangeStatusBarFrame
Notification.Name.UIApplicationDidChangeStatusBarFrame

but they're not posted on the launch of the app, so I wouldn't recommend it.

The simulator has an useful tool to test that.

Hardware->Toggle In-Call Status Bar (⌘Y)

I would suggest you to implement those methods on your `AppDelegate` file. They will be called when the status bar change it's height. One of them it's called before and the other after the change.

Assuming you want that your `ViewController` to be notified when the change occurs, one option, is to send notifications. Like this

First, add this property/variable on `AppDelegate`

// ObjC
@property (assign, nonatomic) CGRect currentStatusBarFrame;

// Swift
var currentStatusBarFrame: CGRect = .zero

then, implement `willChangeStatusBarFrame`

// ObjC
- (void) application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame
{
    self.currentStatusBarFrame = newStatusBarFrame;
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Status Bar Frame Change"
                                                        object:self
                                                      userInfo:@{@"current status bar frame": [NSValue valueWithCGRect:newStatusBarFrame]}];

}

// Swift
func application(_ application: UIApplication, willChangeStatusBarFrame newStatusBarFrame: CGRect) {
    currentStatusBarFrame = newStatusBarFrame
    NotificationCenter.default.post(
        name: NSNotification.Name(rawValue: "Status Bar Frame Change"),
        object: self,
        userInfo: ["current status bar frame": newStatusBarFrame])
}

And we're done with the base of our `Status Bar Frame Checker`. The next part you implement on any `ViewController` that needs to know the status bar frame.

Any time you want to get the status bar frame, you do like so

// ObjC
[(AppDelegate*)[[UIApplication sharedApplication] delegate] currentStatusBarFrame]

// Swift
(UIApplication.shared.delegate as! AppDelegate).currentStatusBarFrame

And to be notified when it changes, add this to `ViewDidLoad` method.

In ObjC

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(statusBarFrameChanged:)
                                             name:@"Status Bar Frame Change"
                                           object:[[UIApplication sharedApplication] delegate]];

And implement this method

- (void) statusBarFrameChanged:(NSNotification*)notification
{
    CGRect newFrame = [[notification.userInfo objectForKey:@"current status bar frame"] CGRectValue];
    NSLog(@"new height %f", CGRectGetHeight(newFrame));
}

In Swift

    NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "Status Bar Frame Change"),
                                           object: nil,
                                           queue: nil) { (note) in
                                            guard let currentStatusBarFrame = note.userInfo?["current status bar frame"] as? CGRect else {return}
                                            print("New Height", currentStatusBarFrame.height)
    }

Problem

How do I detect if user is in-call or tethering? I have a subview for iAd like this: ``` _UIiAD = [[self appdelegate] UIiAD]; _UIiAD.delegate = self; [_UIiAD setFrame:CGRectMake(0,470,320,50)]; [self.view addSubview:_UIiAD];\ ``` And it sets it wrong when the user is in call? How do I detect this?

Original source

Related problems