Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion QMUIKit/UIKitExtensions/NSObject+QMUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
19 changes: 19 additions & 0 deletions QMUIKit/UIKitExtensions/UINavigationBar+QMUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -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"];
}

Expand Down