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?