根據(jù)對應(yīng)的系統(tǒng)版本,實現(xiàn)上會有差異。
iOS 13 之前
主要通過在 appdelegate 中 override touchbegan 事件來實現(xiàn)
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
// iOS 13 之后,點(diǎn)擊狀態(tài)欄的回調(diào)不會進(jìn)入這里,而是在 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)
}
}
還有一種是自己實現(xiàn)一個 UIWindow 覆蓋在 狀態(tài)欄的那一級 UIWindow 上。這里就不記錄了
iOS 13 之后
iOS13: how to detect a status bar click event?
進(jìn)入 iOS 13,touchBegan 的方法不會被調(diào)用到了。網(wǎng)上提供了一種思路來解決。
- 簡而言之,就是通過調(diào)用私有函數(shù),來監(jiān)聽狀態(tài)欄的點(diǎn)擊事件。因此如果是上架的
App不在本文的討論范圍內(nèi)(因為你實現(xiàn)了也沒用,上架會被拒)
實現(xiàn)思路
通過 objective-c 的 category 去復(fù)寫 UIStatusBarManager(iOS 13 之后才提供的 API) 中的私有方法 handleTapAction 實現(xiàn)監(jiān)聽。
注意,swift 的 extension 去實現(xiàn)復(fù)寫私有函數(shù)的方法還沒查到怎么做。如果有知道的歡迎補(bǔ)充。
如果工程采用了 swift,那么這里在添加 objective-c category 實現(xiàn)之后,要在 橋接的 bridge.h 中 import
UIStatusBarManager+CAPHandleTapAction.h
#import <UIKit/UIKit.h>
@interface UIStatusBarManager (CAPHandleTapAction)
/*
使用 category 復(fù)寫私有方法,捕獲狀態(tài)欄的點(diǎn)擊事件
僅當(dāng) iOS 13 以上系統(tǒng),才去監(jiān)聽狀態(tài)欄的點(diǎn)擊事件,iOS 13 之前的,則在 appdelegate 中的 touchesBegan 捕獲
*/
@end
UIStatusBarManager+CAPHandleTapAction.m
#import "UIStatusBarManager+CAPHandleTapAction.h"
@implementation UIStatusBarManager (CAPHandleTapAction)
- (void)handleTapAction:(id)callback {
// 僅當(dāng) iOS 13 以上系統(tǒng),才去監(jiān)聽狀態(tài)欄的點(diǎn)擊事件,iOS 13 之前的,則在 appdelegate 中的 touchesBegan 捕獲
if (@available(iOS 13.0, *)) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"StatusBarTappedNotification"
object:nil];
}
}
@end