处理键盘不能拉起主app的问题
This commit is contained in:
@@ -6,10 +6,14 @@
|
||||
#import "KBFullAccessGuideView.h"
|
||||
#import "Masonry.h"
|
||||
#import "KBResponderUtils.h" // 统一查找 UIInputViewController 的工具
|
||||
#import "KBHUD.h"
|
||||
#import "KBURLOpenBridge.h"
|
||||
|
||||
@interface KBFullAccessGuideView ()
|
||||
@property (nonatomic, strong) UIControl *backdrop;
|
||||
@property (nonatomic, strong) UIView *card;
|
||||
// 预先保存当前键盘控制器,避免运行时通过响应链找不到
|
||||
@property (nonatomic, weak) UIInputViewController *ivc;
|
||||
@end
|
||||
|
||||
@implementation KBFullAccessGuideView
|
||||
@@ -110,7 +114,8 @@
|
||||
}
|
||||
|
||||
- (void)presentIn:(UIView *)parent {
|
||||
UIView *container = parent.window ?: parent;
|
||||
if (!parent) return;
|
||||
UIView *container = parent; // 关键:加到键盘视图树中,而不是 window
|
||||
self.frame = container.bounds;
|
||||
self.alpha = 0;
|
||||
[container addSubview:self];
|
||||
@@ -126,15 +131,19 @@
|
||||
|
||||
+ (void)showInView:(UIView *)parent {
|
||||
if (!parent) return;
|
||||
// 避免重复
|
||||
for (UIView *v in (parent.window ?: parent).subviews) {
|
||||
// 避免重复(仅在 parent 层级检查)
|
||||
for (UIView *v in parent.subviews) {
|
||||
if ([v isKindOfClass:[KBFullAccessGuideView class]]) return;
|
||||
}
|
||||
[[KBFullAccessGuideView build] presentIn:parent];
|
||||
KBFullAccessGuideView *view = [KBFullAccessGuideView build];
|
||||
// 预取 ivc
|
||||
view.ivc = KBFindInputViewController(parent);
|
||||
[view presentIn:parent];
|
||||
}
|
||||
|
||||
+ (void)dismissFromView:(UIView *)parent {
|
||||
UIView *container = parent.window ?: parent;
|
||||
UIView *container = parent;
|
||||
if (!container) return;
|
||||
for (UIView *v in container.subviews) {
|
||||
if ([v isKindOfClass:[KBFullAccessGuideView class]]) {
|
||||
[(KBFullAccessGuideView *)v dismiss];
|
||||
@@ -148,30 +157,73 @@
|
||||
#pragma mark - Actions
|
||||
|
||||
// 工具方法已提取到 KBResponderUtils.h
|
||||
|
||||
// 打开主 App,引导用户去系统设置开启完全访问:优先 Scheme,失败再试 UL;仍失败则提示手动路径。
|
||||
- (void)onTapGoEnable {
|
||||
// 在扩展中无法使用 UIApplication。改为委托宿主打开链接:
|
||||
// 方案:优先拉起主 App 并由主 App 打开设置页,避免宿主拦截。
|
||||
UIInputViewController *ivc = KBFindInputViewController(self);
|
||||
if (!ivc) { [self dismiss]; return; }
|
||||
|
||||
// 先尝试 Universal Link(如未配置可改为你的域名),失败再用自定义 scheme。
|
||||
|
||||
// 自定义 Scheme(App 里在 openURL 中转到设置页)
|
||||
// 统一使用主 App 的自定义 Scheme
|
||||
NSURL *scheme = [NSURL URLWithString:[NSString stringWithFormat:@"%@@//settings?src=kb_extension", KB_APP_SCHEME]];
|
||||
// Universal Link(需 AASA/Associated Domains 配置且 KB_UL_BASE 与域名一致)
|
||||
NSURL *ul = [NSURL URLWithString:[NSString stringWithFormat:@"%@?src=kb_extension", KB_UL_SETTINGS]];
|
||||
void (^fallback)(void) = ^{
|
||||
NSURL *scheme = [NSURL URLWithString:@"kbkeyboard://settings?src=kb_extension"]; // 主App在 openURL 中处理
|
||||
[ivc.extensionContext openURL:scheme completionHandler:^(__unused BOOL ok2) {
|
||||
// 无论成功与否,都收起当前提示层,避免遮挡
|
||||
[self dismiss];
|
||||
}];
|
||||
|
||||
void (^finish)(BOOL) = ^(BOOL ok){
|
||||
if (ok) { [self dismiss]; }
|
||||
else {
|
||||
[KBHUD showInfo:@"无法自动打开,请按路径:设置→通用→键盘→键盘→恋爱键盘→允许完全访问"]; // 失败兜底提示
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 先试 Scheme(更可能被宿主允许直接拉起 App)
|
||||
if (scheme) {
|
||||
[ivc.extensionContext openURL:scheme completionHandler:^(BOOL ok) {
|
||||
if (ok) { finish(YES); return; }
|
||||
if (ul) {
|
||||
[ivc.extensionContext openURL:ul completionHandler:^(BOOL ok2) {
|
||||
if (ok2) { finish(YES); return; }
|
||||
// 兜底:在用户点击触发的场景下,尝试通过响应链调用 openURL:
|
||||
BOOL bridged = NO;
|
||||
@try {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
bridged = [KBURLOpenBridge openURLViaResponder:scheme from:self];
|
||||
if (!bridged && ul) {
|
||||
bridged = [KBURLOpenBridge openURLViaResponder:ul from:self];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
} @catch (__unused NSException *e) { bridged = NO; }
|
||||
finish(bridged);
|
||||
}];
|
||||
} else {
|
||||
// 没有 UL,则直接尝试桥接 Scheme
|
||||
BOOL bridged = NO;
|
||||
@try {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
bridged = [KBURLOpenBridge openURLViaResponder:scheme from:self];
|
||||
#pragma clang diagnostic pop
|
||||
} @catch (__unused NSException *e) { bridged = NO; }
|
||||
finish(bridged);
|
||||
}
|
||||
}];
|
||||
return;
|
||||
}
|
||||
// 无 scheme 时,直接尝试 UL
|
||||
if (ul) {
|
||||
[ivc.extensionContext openURL:ul completionHandler:^(BOOL ok) {
|
||||
if (ok) { [self dismiss]; }
|
||||
else { fallback(); }
|
||||
if (ok) { finish(YES); return; }
|
||||
BOOL bridged = NO;
|
||||
@try {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
bridged = [KBURLOpenBridge openURLViaResponder:ul from:self];
|
||||
#pragma clang diagnostic pop
|
||||
} @catch (__unused NSException *e) { bridged = NO; }
|
||||
finish(bridged);
|
||||
}];
|
||||
} else {
|
||||
fallback();
|
||||
finish(NO);
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user