// // KeyBoardPrefixHeader.pch // keyBoard // // Created by Mac on 2025/10/27. // #ifndef KeyBoardPrefixHeader_pch #define KeyBoardPrefixHeader_pch //Bugly #define BuglyId @"5736ce7a19" /// 三方 #import // 公共配置 #import "KBConfig.h" #import "KBAPI.h" // 接口路径宏(统一管理) #import "KBLoginVM.h" // 登录 VM(Apple 登录复用) /// 系统 #import #import "KBHUD.h" #import "KBAlert.h" #import "KBNetworkManager.h" /// 项目 #import "KBNetworkManager.h" #import "UIView+KBShadow.h" #import "UIImage+KBColor.h" #import "UIColor+Extension.h" #import "UIViewController+Extension.h" #import "BaseNavigationController.h" #import "BaseTableView.h" #import "BaseCell.h" #import "BaseViewController.h" #import "KBLocalizationManager.h" // 全局多语言封装 //-----------------------------------------------宏定义全局----------------------------------------------------------/ // 调试专用日志(DEBUG 打印,RELEASE 不打印)。尽量显眼,包含函数与行号。 #if DEBUG #define KBLOG(fmt, ...) do { \ NSString *kb_msg__ = [NSString stringWithFormat:(fmt), ##__VA_ARGS__]; \ NSLog(@"\n==============================[KB DEBUG]==============================\n[Function] %s\n[Line] %d\n%@\n=====================================================================\n", __PRETTY_FUNCTION__, __LINE__, kb_msg__); \ } while(0) #else #define KBLOG(...) #endif // 通用链接(Universal Links)统一配置 // 仅需修改这里的域名/前缀,工程内所有使用 UL 的地方都会同步。 #define KB_UL_BASE @"https://app.tknb.net/ul" // 与 Associated Domains 一致 #define KB_UL_LOGIN KB_UL_BASE @"/login" #define KB_UL_SETTINGS KB_UL_BASE @"/settings" /// 第一次安装 #define KBSexSelectShownKey @"kKBSexSelectShownKey" /// UI 尺寸/设备宏 // 屏幕尺寸 #define KB_SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width) #define KB_SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height) #define KB_ONE_PIXEL (1.0 / [UIScreen mainScreen].scale) // 基础高度 #define KB_NAVBAR_BASE_HEIGHT 44.0 #define KB_TABBAR_BASE_HEIGHT 49.0 #define COLOR_WITH_RGB(R,G,B,A) [UIColor colorWithRed:R green:G blue:B alpha:A] /// 主题色 绿色 #define KBColorValue 0x02BEAC /// 通用黑色 #define KBBlackValue 0x1B1F1A // 当前 KeyWindow(iOS 13 场景化兼容) static inline UIWindow *KB_KeyWindow(void) { UIWindow *window = nil; if (@available(iOS 13.0, *)) { for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) { if (scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:[UIWindowScene class]]) { UIWindowScene *ws = (UIWindowScene *)scene; for (UIWindow *w in ws.windows) { if (w.isKeyWindow) { window = w; break; } } if (window) { break; } } } if (!window) { window = UIApplication.sharedApplication.windows.firstObject; } } else { window = UIApplication.sharedApplication.keyWindow; } return window; } // Safe Area static inline UIEdgeInsets KB_SafeAreaInsets(void) { if (@available(iOS 11.0, *)) { UIWindow *w = KB_KeyWindow(); return w ? w.safeAreaInsets : UIEdgeInsetsZero; } return UIEdgeInsetsZero; } static inline CGFloat KB_SafeAreaTop(void) { return KB_SafeAreaInsets().top; } static inline CGFloat KB_SafeAreaBottom(void) { return KB_SafeAreaInsets().bottom; } // 状态栏高度(iOS13+ 兼容) static inline CGFloat KB_StatusBarHeight(void) { if (@available(iOS 13.0, *)) { UIWindow *w = KB_KeyWindow(); UIStatusBarManager *m = w.windowScene.statusBarManager; return m ? m.statusBarFrame.size.height : 0.0; } else { return UIApplication.sharedApplication.statusBarFrame.size.height; } } // 导航栏+状态栏总高度、TabBar 高度、是否异形屏 #define KB_STATUSBAR_HEIGHT (KB_StatusBarHeight()) #define KB_NAV_TOTAL_HEIGHT (KB_NAVBAR_BASE_HEIGHT + KB_StatusBarHeight()) #define KB_TABBAR_HEIGHT (KB_TABBAR_BASE_HEIGHT + KB_SafeAreaBottom()) #define KB_IS_IPHONEX_SERIES (KB_SafeAreaBottom() > 0.0) // 屏幕底部安全区高度(Home 指示条区域高度)。 // 说明:带刘海/异形屏通常为 34,非异形屏为 0;随横竖屏、安全区变动而变。 #ifndef KB_SAFE_BOTTOM #define KB_SAFE_BOTTOM (KB_SafeAreaBottom()) #endif // --- 设备特性:是否为带刘海机型(iPhone X 及以后异形屏)--- // 说明:在 iPhone 12 等机型底部会有 34px 安全区,这里通过安全区来判断是否为“刘海屏”。 // 注意:使用到 UIKit,这里自行引入,避免依赖 PCH 的包含顺序。 #import static inline BOOL KBDeviceHasNotchRuntime(void) { if (@available(iOS 11.0, *)) { UIWindow *window = nil; if (@available(iOS 13.0, *)) { for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) { if (scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:[UIWindowScene class]]) { UIWindowScene *ws = (UIWindowScene *)scene; for (UIWindow *w in ws.windows) { if (w.isKeyWindow) { window = w; break; } } if (window) { break; } } } if (!window) { window = UIApplication.sharedApplication.windows.firstObject; } } else { window = UIApplication.sharedApplication.keyWindow; } return window.safeAreaInsets.bottom > 0.0; } return NO; } #ifndef KB_DEVICE_HAS_NOTCH #define KB_DEVICE_HAS_NOTCH (KBDeviceHasNotchRuntime()) #endif // --- 获取当前可用的 UINavigationController --- // 说明: // 1. 优先取最顶层可见 VC(见 UIViewController+Extension),再解析其所在的导航容器; // 2. 兼容被 UITabBarController 包裹、直接为 UINavigationController、或普通 VC 嵌套等场景; // 3. 若无法获取,返回 nil。 static inline __kindof UINavigationController *KB_CurrentNavigationController(void) { UIViewController *top = [UIViewController kb_topMostViewController]; if (!top) { UIWindow *w = KB_KeyWindow(); top = w.rootViewController; } if (!top) return nil; // 直接就是导航控制器 if ([top isKindOfClass:[UINavigationController class]]) { return (UINavigationController *)top; } // 顶层是 TabBar,取选中的子控制器 if ([top isKindOfClass:[UITabBarController class]]) { UITabBarController *tab = (UITabBarController *)top; UIViewController *sel = tab.selectedViewController ?: tab.viewControllers.firstObject; if ([sel isKindOfClass:[UINavigationController class]]) return (UINavigationController *)sel; return sel.navigationController ?: nil; } // 普通 VC,取其所属导航 if (top.navigationController) return top.navigationController; // 兜底:尝试从 root 解析 UIViewController *root = KB_KeyWindow().rootViewController; if ([root isKindOfClass:[UINavigationController class]]) return (UINavigationController *)root; if ([root isKindOfClass:[UITabBarController class]]) { UIViewController *sel = ((UITabBarController *)root).selectedViewController; if ([sel isKindOfClass:[UINavigationController class]]) return (UINavigationController *)sel; return sel.navigationController ?: nil; } return nil; } // 简便宏:直接当做属性来用,例如:`[KB_CURRENT_NAV pushViewController:vc animated:YES];` #ifndef KB_CURRENT_NAV #define KB_CURRENT_NAV (KB_CurrentNavigationController()) #endif #endif /* KeyBoardPrefixHeader_pch */