From 0de42863214dfc0c9dd63ae3ba2bd323006d0b97 Mon Sep 17 00:00:00 2001 From: wsr1949 <921903719@qq.com> Date: Tue, 11 Nov 2025 18:31:40 +0800 Subject: [PATCH 1/2] Implement qmui_contentView method for UINavigationBar Add method to retrieve contentView for UINavigationBar in iOS 26 and later. --- .../UIKitExtensions/UINavigationBar+QMUI.m | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/QMUIKit/UIKitExtensions/UINavigationBar+QMUI.m b/QMUIKit/UIKitExtensions/UINavigationBar+QMUI.m index 8d82a777..cb596c4f 100644 --- a/QMUIKit/UIKitExtensions/UINavigationBar+QMUI.m +++ b/QMUIKit/UIKitExtensions/UINavigationBar+QMUI.m @@ -359,6 +359,25 @@ + (void)load { } - (UIView *)qmui_contentView { + if (@available(iOS 26.0, *)) { + // 如果 contentView 已经被构造出来,则通过遍历 view 层级树的方式获取 + UIView *contentView = [self.subviews qmui_firstMatchWithBlock:^BOOL(__kindof UIView * _Nonnull item) { + return [NSStringFromClass(item.class) containsString:@"ContentView"]; + }]; + if (contentView) return contentView; + + // Xcode 26 编译在 iOS 26 上时,无法用以前的 KVC 方式获取 contentView,所以改为通过 Ivar 获取 + NSObject *provider = [self valueForKey:@"visualProvider"]; + __block UIView *result = nil; + [provider qmui_enumrateIvarsUsingBlock:^(Ivar _Nonnull ivar, NSString * _Nonnull ivarDescription) { + if (!result && [ivarDescription containsString:@"contentView"]) { + result = getObjectIvarValue(provider, ivar); + } + }]; + return result; + } + + // 在 bar init 完即可获取到 contentView,虽然此时尚未被添加到 view 上 return [self valueForKeyPath:@"visualProvider.contentView"]; } From 65b494f346f39541001509b480d3b4c2f9202c0a Mon Sep 17 00:00:00 2001 From: "921903719@qq.com" <921903719@qq.com> Date: Thu, 12 Mar 2026 17:47:10 +0800 Subject: [PATCH 2/2] Update NSObject+QMUI.m --- QMUIKit/UIKitExtensions/NSObject+QMUI.m | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/QMUIKit/UIKitExtensions/NSObject+QMUI.m b/QMUIKit/UIKitExtensions/NSObject+QMUI.m index 9fd21b90..2346bb32 100644 --- a/QMUIKit/UIKitExtensions/NSObject+QMUI.m +++ b/QMUIKit/UIKitExtensions/NSObject+QMUI.m @@ -262,7 +262,25 @@ @implementation NSObject (QMUI_KeyValueCoding) - (id)qmui_valueForKey:(NSString *)key { if ([self isKindOfClass:[UIView class]] && QMUICMIActivated && !IgnoreKVCAccessProhibited) { BeginIgnoreUIKVCAccessProhibited - id value = [self valueForKey:key]; + + id value = nil; + // 修复:增加 KVC 键合法性校验,避免访问未定义的 key 导致崩溃 + if ([self respondsToSelector:NSSelectorFromString(key)] || + [self.class instancesRespondToSelector:NSSelectorFromString(key)] || + [self.class accessInstanceVariablesDirectly]) { + // 方式1:优先通过 selector 访问(方法/属性) + SEL getterSel = NSSelectorFromString(key); + if ([self respondsToSelector:getterSel]) { + value = ((id (*)(id, SEL))objc_msgSend)(self, getterSel); + } else { + // 方式2:校验实例变量存在性后再通过 KVC 访问 + Ivar ivar = class_getInstanceVariable([self class], [key UTF8String]); + if (ivar) { + value = [self valueForKey:key]; + } + } + } + EndIgnoreUIKVCAccessProhibited return value; }