检测用户是不是有通话状态栏

Posted

技术标签:

【中文标题】检测用户是不是有通话状态栏【英文标题】:Detecting if user has in call status bar检测用户是否有通话状态栏 【发布时间】:2014-07-13 12:47:20 【问题描述】:

如何检测用户是通话中还是网络共享?我有一个这样的 iAd 子视图:

_UIiAD = [[self appdelegate] UIiAD];
_UIiAD.delegate = self;

[_UIiAD setFrame:CGRectMake(0,470,320,50)];
[self.view addSubview:_UIiAD];\

当用户通话时它设置错误?如何检测到这一点?

【问题讨论】:

【参考方案1】:

UIApplicationDelegate有这两种方法。

// 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)

还有Notifications

//ObjC
UIApplicationWillChangeStatusBarFrameNotification
UIApplicationDidChangeStatusBarFrameNotification

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

但它们没有在应用程序启动时发布,所以我不推荐它。

模拟器有一个有用的工具来测试它。

硬件->切换通话状态栏 (⌘Y)

我建议您在 AppDelegate 文件中实现这些方法。当状态栏改变它的高度时,它们将被调用。其中一个在更改之前调用,另一个在更改之后调用。

假设您希望在更改发生时通知您的ViewController,一种选择是发送通知。像这样

首先,在AppDelegate上添加这个属性/变量

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

// Swift
var currentStatusBarFrame: CGRect = .zero

然后,实现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])

我们已经完成了Status Bar Frame Checker 的基础。您在任何需要知道状态栏框架的ViewController 上实现的下一部分。

任何时候你想得到状态栏框架,你都这样做

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

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

若要在更改时收到通知,请将其添加到 ViewDidLoad 方法中。

在 ObjC 中

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

并实现这个方法

- (void) statusBarFrameChanged:(NSNotification*)notification

    CGRect newFrame = [[notification.userInfo objectForKey:@"current status bar frame"] CGRectValue];
    NSLog(@"new height %f", CGRectGetHeight(newFrame));

在斯威夫特中

    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)
    

【讨论】:

正确的答案是首先不要使用硬编码的数字进行布局,而是使用自动布局、自动调整掩码或根据您在 layoutSubviews 中的当前大小进行调整,而不是实际监控状态栏的状态。 (例如,出于同样的原因,OP 的代码在 3.5" 显示器上不起作用。) 对如何在横向中执行此操作有任何想法吗?在横向中,状态栏不会在调用中改变高度,因此永远不会调用框架更改通知。 我想你想用 UIApplicationWillChangeStatusBarFrameNotification 改变“状态栏框架改变”【参考方案2】:

我相信你有状态栏问题,这让你看到向下移动。你可以使用下面的代码来解决这个问题

迅速

self.tabBarController?.tabBar.autoresizingMask = UIViewAutoresizing(rawValue: UIViewAutoresizing.RawValue(UInt8(UIViewAutoresizing.flexibleWidth.rawValue) | UInt8(UIViewAutoresizing.flexibleTopMargin.rawValue)))

它解决了我在用户通话时由状态栏引起的问题。用于目标 C 参考 click here

【讨论】:

以上是关于检测用户是不是有通话状态栏的主要内容,如果未能解决你的问题,请参考以下文章

通话时iOS状态栏高度不正确

当用户在通话状态栏中时,导航栏布局出现异常

如何检测双高状态栏?

状态栏高度变化处理

UIViewController 通话状态栏问题

在启用通话状态栏的情况下打开应用程序时的 iOS 标签栏问题