由于iOS13及以后引入了SceneDelegate,导致不能通过原来的[UIApplication sharedApplication].keyWindow直接获取到正确的keyWindow。需要区分系统来获取。具体的实现如下:
/** 获取 keyWindow */
static inline UIWindow *BRGetKeyWindow(void) {
UIWindow *keyWindow = nil;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 // 编译时检查SDK版本:Xcode11+编译会调用(iOS SDK 13.0 以后版本的处理)
if (@available(iOS 13.0, *)) {
NSSet<UIScene *> *connectedScenes = [UIApplication sharedApplication].connectedScenes;
for (UIScene *scene in connectedScenes) {
if (scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:[UIWindowScene class]]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
for (UIWindow *window in windowScene.windows) {
if (window.isKeyWindow) {
keyWindow = window;
break;
}
}
}
}
} else
#endif
{
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
return [UIApplication sharedApplication].keyWindow;
#endif
}
return keyWindow;
}
内联函数的使用和宏类似,它主要为了代替无检查机制的宏,具体使用如下:
#define Base_BottomHeight ([FMConfig config].safeBottomHeight)
// 底部安全区域高度
#define BR_BOTTOM_MARGIN \
({CGFloat safeBottomHeight = 0;\
if (@available(iOS 11.0, *)) {\
safeBottomHeight = BRGetKeyWindow().safeAreaInsets.bottom;\
}\
(safeBottomHeight);})