Statusbar 捕获状态栏的点击事件(ios 13及 ios 13 之前)

根据对应的系统版本,实现上会有差异。

iOS 13 之前

主要通过在 appdelegate 中 override touchbegan 事件来实现

override func touchesBegan(_ touches: Set, 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-ccategory 去复写 UIStatusBarManager(iOS 13 之后才提供的 API) 中的私有方法 handleTapAction 实现监听。

注意,swift 的 extension 去实现复写私有函数的方法还没查到怎么做。如果有知道的欢迎补充。
如果工程采用了 swift,那么这里在添加 objective-c category 实现之后,要在 桥接的 bridge.h 中 import

UIStatusBarManager+CAPHandleTapAction.h

#import 

@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

你可能感兴趣的:(Statusbar 捕获状态栏的点击事件(ios 13及 ios 13 之前))