根据对应的系统版本,实现上会有差异。
iOS 13 之前
主要通过在 appdelegate 中 override touchbegan 事件来实现
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
// iOS 13 之后,点击状态栏的回调不会进入这里,而是在 UIStatusBarManager+CAPHandleTapAction 中处理
if #available(iOS 13.0, *) {
return
}
let statusBarRect = UIApplication.shared.statusBarFrame
guard let touchPoint = event?.allTouches?.first?.location(in: self.window) else { return }
if statusBarRect.contains(touchPoint) {
NotificationCenter.default.post(name: StatusBarTappedNotification.name, object: nil)
}
}
还有一种是自己实现一个 UIWindow
覆盖在 状态栏的那一级 UIWindow
上。这里就不记录了
iOS 13 之后
iOS13: how to detect a status bar click event?
进入 iOS 13,touchBegan 的方法不会被调用到了。网上提供了一种思路来解决。
- 简而言之,就是通过调用私有函数,来监听状态栏的点击事件。因此如果是上架的
App
不在本文的讨论范围内(因为你实现了也没用,上架会被拒)
实现思路
通过 objective-c
的 category
去复写 UIStatusBarManager
(iOS 13 之后才提供的 API) 中的私有方法 handleTapAction
实现监听。
注意,swift 的 extension 去实现复写私有函数的方法还没查到怎么做。如果有知道的欢迎补充。
如果工程采用了 swift,那么这里在添加 objective-c category 实现之后,要在 桥接的 bridge.h 中 import
UIStatusBarManager+CAPHandleTapAction.h
#import <UIKit/UIKit.h>
@interface UIStatusBarManager (CAPHandleTapAction)
/*
使用 category 复写私有方法,捕获状态栏的点击事件
仅当 iOS 13 以上系统,才去监听状态栏的点击事件,iOS 13 之前的,则在 appdelegate 中的 touchesBegan 捕获
*/
@end
UIStatusBarManager+CAPHandleTapAction.m
#import "UIStatusBarManager+CAPHandleTapAction.h"
@implementation UIStatusBarManager (CAPHandleTapAction)
- (void)handleTapAction:(id)callback {
// 仅当 iOS 13 以上系统,才去监听状态栏的点击事件,iOS 13 之前的,则在 appdelegate 中的 touchesBegan 捕获
if (@available(iOS 13.0, *)) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"StatusBarTappedNotification"
object:nil];
}
}
@end