1
This commit is contained in:
@@ -8,23 +8,26 @@
|
|||||||
#import "KeyboardViewController.h"
|
#import "KeyboardViewController.h"
|
||||||
#import "KBKeyBoardMainView.h"
|
#import "KBKeyBoardMainView.h"
|
||||||
|
|
||||||
#import "KBKey.h"
|
|
||||||
#import "KBFunctionView.h"
|
|
||||||
#import "KBSettingView.h"
|
|
||||||
#import "Masonry.h"
|
|
||||||
#import "KBAuthManager.h"
|
#import "KBAuthManager.h"
|
||||||
#import "KBFullAccessManager.h"
|
|
||||||
#import "KBSkinManager.h"
|
|
||||||
#import "KBSkinInstallBridge.h"
|
|
||||||
#import "KBHostAppLauncher.h"
|
|
||||||
#import "KBKeyboardSubscriptionView.h"
|
|
||||||
#import "KBKeyboardSubscriptionProduct.h"
|
|
||||||
#import "KBBackspaceUndoManager.h"
|
#import "KBBackspaceUndoManager.h"
|
||||||
|
#import "KBFullAccessManager.h"
|
||||||
|
#import "KBFunctionView.h"
|
||||||
|
#import "KBHostAppLauncher.h"
|
||||||
#import "KBInputBufferManager.h"
|
#import "KBInputBufferManager.h"
|
||||||
|
#import "KBKey.h"
|
||||||
|
#import "KBKeyboardSubscriptionProduct.h"
|
||||||
|
#import "KBKeyboardSubscriptionView.h"
|
||||||
|
#import "KBSettingView.h"
|
||||||
|
#import "KBSkinInstallBridge.h"
|
||||||
|
#import "KBSkinManager.h"
|
||||||
#import "KBSuggestionEngine.h"
|
#import "KBSuggestionEngine.h"
|
||||||
|
#import "Masonry.h"
|
||||||
|
#import "UIImage+KBColor.h"
|
||||||
|
|
||||||
// #import "KBLog.h"
|
// #import "KBLog.h"
|
||||||
|
|
||||||
// 提前声明一个类别,使编译器在 static 回调中识别 kb_consumePendingShopSkin 方法。
|
// 提前声明一个类别,使编译器在 static 回调中识别 kb_consumePendingShopSkin
|
||||||
|
// 方法。
|
||||||
@interface KeyboardViewController (KBSkinShopBridge)
|
@interface KeyboardViewController (KBSkinShopBridge)
|
||||||
- (void)kb_consumePendingShopSkin;
|
- (void)kb_consumePendingShopSkin;
|
||||||
@end
|
@end
|
||||||
@@ -37,12 +40,14 @@ static NSString * const kKBDefaultSkinIdDark = @"normal_hei_them";
|
|||||||
static NSString *const kKBDefaultSkinZipNameDark = @"normal_hei_them";
|
static NSString *const kKBDefaultSkinZipNameDark = @"normal_hei_them";
|
||||||
|
|
||||||
static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
||||||
void *observer,
|
void *observer, CFStringRef name,
|
||||||
CFStringRef name,
|
|
||||||
const void *object,
|
const void *object,
|
||||||
CFDictionaryRef userInfo) {
|
CFDictionaryRef userInfo) {
|
||||||
KeyboardViewController *strongSelf = (__bridge KeyboardViewController *)observer;
|
KeyboardViewController *strongSelf =
|
||||||
if (!strongSelf) { return; }
|
(__bridge KeyboardViewController *)observer;
|
||||||
|
if (!strongSelf) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
if ([strongSelf respondsToSelector:@selector(kb_consumePendingShopSkin)]) {
|
if ([strongSelf respondsToSelector:@selector(kb_consumePendingShopSkin)]) {
|
||||||
[strongSelf kb_consumePendingShopSkin];
|
[strongSelf kb_consumePendingShopSkin];
|
||||||
@@ -50,11 +55,16 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@interface KeyboardViewController () <KBKeyBoardMainViewDelegate, KBFunctionViewDelegate, KBKeyboardSubscriptionViewDelegate>
|
@interface KeyboardViewController () <KBKeyBoardMainViewDelegate,
|
||||||
@property (nonatomic, strong) UIButton *nextKeyboardButton; // 系统“下一个键盘”按钮(可选)
|
KBFunctionViewDelegate,
|
||||||
|
KBKeyboardSubscriptionViewDelegate>
|
||||||
|
@property(nonatomic, strong)
|
||||||
|
UIButton *nextKeyboardButton; // 系统“下一个键盘”按钮(可选)
|
||||||
@property(nonatomic, strong) UIView *contentView;
|
@property(nonatomic, strong) UIView *contentView;
|
||||||
@property (nonatomic, strong) KBKeyBoardMainView *keyBoardMainView; // 功能面板视图(点击工具栏第0个时显示)
|
@property(nonatomic, strong) KBKeyBoardMainView
|
||||||
@property (nonatomic, strong) KBFunctionView *functionView; // 功能面板视图(点击工具栏第0个时显示)
|
*keyBoardMainView; // 功能面板视图(点击工具栏第0个时显示)
|
||||||
|
@property(nonatomic, strong)
|
||||||
|
KBFunctionView *functionView; // 功能面板视图(点击工具栏第0个时显示)
|
||||||
@property(nonatomic, strong) KBSettingView *settingView; // 设置页
|
@property(nonatomic, strong) KBSettingView *settingView; // 设置页
|
||||||
@property(nonatomic, strong) UIImageView *bgImageView; // 背景图(在底层)
|
@property(nonatomic, strong) UIImageView *bgImageView; // 背景图(在底层)
|
||||||
@property(nonatomic, strong) KBKeyboardSubscriptionView *subscriptionView;
|
@property(nonatomic, strong) KBKeyboardSubscriptionView *subscriptionView;
|
||||||
@@ -86,24 +96,30 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[KBHUD setContainerView:self.view];
|
[KBHUD setContainerView:self.view];
|
||||||
// 绑定完全访问管理器,便于统一感知和联动网络开关
|
// 绑定完全访问管理器,便于统一感知和联动网络开关
|
||||||
[[KBFullAccessManager shared] bindInputController:self];
|
[[KBFullAccessManager shared] bindInputController:self];
|
||||||
__unused id token = [[NSNotificationCenter defaultCenter] addObserverForName:KBFullAccessChangedNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(__unused NSNotification * _Nonnull note) {
|
__unused id token = [[NSNotificationCenter defaultCenter]
|
||||||
|
addObserverForName:KBFullAccessChangedNotification
|
||||||
|
object:nil
|
||||||
|
queue:[NSOperationQueue mainQueue]
|
||||||
|
usingBlock:^(__unused NSNotification *_Nonnull note){
|
||||||
// 如需,可在此刷新与完全访问相关的 UI
|
// 如需,可在此刷新与完全访问相关的 UI
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 皮肤变化时,立即应用
|
// 皮肤变化时,立即应用
|
||||||
__unused id token2 = [[NSNotificationCenter defaultCenter] addObserverForName:KBSkinDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(__unused NSNotification * _Nonnull note) {
|
__unused id token2 = [[NSNotificationCenter defaultCenter]
|
||||||
|
addObserverForName:KBSkinDidChangeNotification
|
||||||
|
object:nil
|
||||||
|
queue:[NSOperationQueue mainQueue]
|
||||||
|
usingBlock:^(__unused NSNotification *_Nonnull note) {
|
||||||
[self kb_applyTheme];
|
[self kb_applyTheme];
|
||||||
}];
|
}];
|
||||||
[self kb_applyTheme];
|
[self kb_applyTheme];
|
||||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
|
CFNotificationCenterAddObserver(
|
||||||
(__bridge const void *)(self),
|
CFNotificationCenterGetDarwinNotifyCenter(),
|
||||||
KBSkinInstallNotificationCallback,
|
(__bridge const void *)(self), KBSkinInstallNotificationCallback,
|
||||||
(__bridge CFStringRef)KBDarwinSkinInstallRequestNotification,
|
(__bridge CFStringRef)KBDarwinSkinInstallRequestNotification, NULL,
|
||||||
NULL,
|
|
||||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||||
[self kb_consumePendingShopSkin];
|
[self kb_consumePendingShopSkin];
|
||||||
[self kb_applyDefaultSkinIfNeeded];
|
[self kb_applyDefaultSkinIfNeeded];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillAppear:(BOOL)animated {
|
- (void)viewWillAppear:(BOOL)animated {
|
||||||
@@ -112,9 +128,13 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[[KBBackspaceUndoManager shared] registerNonClearAction];
|
[[KBBackspaceUndoManager shared] registerNonClearAction];
|
||||||
[[KBInputBufferManager shared] resetWithText:@""];
|
[[KBInputBufferManager shared] resetWithText:@""];
|
||||||
[[KBLocalizationManager shared] reloadFromSharedStorageIfNeeded];
|
[[KBLocalizationManager shared] reloadFromSharedStorageIfNeeded];
|
||||||
// 注意:微信/QQ 等宿主的 documentContext 可能是“截断窗口”,这里只更新 liveText,不要把它当作全文 manualSnapshot。
|
// 注意:微信/QQ 等宿主的 documentContext 可能是“截断窗口”,这里只更新
|
||||||
[[KBInputBufferManager shared] updateFromExternalContextBefore:self.textDocumentProxy.documentContextBeforeInput
|
// liveText,不要把它当作全文 manualSnapshot。
|
||||||
after:self.textDocumentProxy.documentContextAfterInput];
|
[[KBInputBufferManager shared]
|
||||||
|
updateFromExternalContextBefore:self.textDocumentProxy
|
||||||
|
.documentContextBeforeInput
|
||||||
|
after:self.textDocumentProxy
|
||||||
|
.documentContextAfterInput];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillDisappear:(BOOL)animated {
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
@@ -125,7 +145,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
|
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
|
||||||
[super traitCollectionDidChange:previousTraitCollection];
|
[super traitCollectionDidChange:previousTraitCollection];
|
||||||
if (@available(iOS 13.0, *)) {
|
if (@available(iOS 13.0, *)) {
|
||||||
if (previousTraitCollection.userInterfaceStyle != self.traitCollection.userInterfaceStyle) {
|
if (previousTraitCollection.userInterfaceStyle !=
|
||||||
|
self.traitCollection.userInterfaceStyle) {
|
||||||
[self kb_applyDefaultSkinIfNeeded];
|
[self kb_applyDefaultSkinIfNeeded];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,11 +154,13 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
|
|
||||||
- (void)textDidChange:(id<UITextInput>)textInput {
|
- (void)textDidChange:(id<UITextInput>)textInput {
|
||||||
[super textDidChange:textInput];
|
[super textDidChange:textInput];
|
||||||
[[KBInputBufferManager shared] updateFromExternalContextBefore:self.textDocumentProxy.documentContextBeforeInput
|
[[KBInputBufferManager shared]
|
||||||
after:self.textDocumentProxy.documentContextAfterInput];
|
updateFromExternalContextBefore:self.textDocumentProxy
|
||||||
|
.documentContextBeforeInput
|
||||||
|
after:self.textDocumentProxy
|
||||||
|
.documentContextAfterInput];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)setupUI {
|
- (void)setupUI {
|
||||||
self.view.translatesAutoresizingMaskIntoConstraints = NO;
|
self.view.translatesAutoresizingMaskIntoConstraints = NO;
|
||||||
|
|
||||||
@@ -147,8 +170,10 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
CGFloat screenWidth = CGRectGetWidth([UIScreen mainScreen].bounds);
|
CGFloat screenWidth = CGRectGetWidth([UIScreen mainScreen].bounds);
|
||||||
CGFloat outerVerticalInset = KBFit(4.0f);
|
CGFloat outerVerticalInset = KBFit(4.0f);
|
||||||
|
|
||||||
NSLayoutConstraint *h = [self.view.heightAnchor constraintEqualToConstant:keyboardHeight];
|
NSLayoutConstraint *h =
|
||||||
NSLayoutConstraint *w = [self.view.widthAnchor constraintEqualToConstant:screenWidth];
|
[self.view.heightAnchor constraintEqualToConstant:keyboardHeight];
|
||||||
|
NSLayoutConstraint *w =
|
||||||
|
[self.view.widthAnchor constraintEqualToConstant:screenWidth];
|
||||||
self.kb_heightConstraint = h;
|
self.kb_heightConstraint = h;
|
||||||
self.kb_widthConstraint = w;
|
self.kb_widthConstraint = w;
|
||||||
|
|
||||||
@@ -189,14 +214,14 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
|
|
||||||
// MARK: - Suggestions
|
// MARK: - Suggestions
|
||||||
|
|
||||||
- (void)kb_updateCurrentWordWithInsertedText:(NSString *)text {
|
- (void)kb_updateCurrentWordWithInsertedText:(NSString *)text {
|
||||||
if (text.length == 0) { return; }
|
if (text.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ([self kb_isAlphabeticString:text]) {
|
if ([self kb_isAlphabeticString:text]) {
|
||||||
NSString *current = self.currentWord ?: @"";
|
NSString *current = self.currentWord ?: @"";
|
||||||
self.currentWord = [current stringByAppendingString:text];
|
self.currentWord = [current stringByAppendingString:text];
|
||||||
@@ -215,11 +240,13 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
|
|
||||||
- (void)kb_scheduleContextRefreshResetSuppression:(BOOL)resetSuppression {
|
- (void)kb_scheduleContextRefreshResetSuppression:(BOOL)resetSuppression {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[self kb_refreshCurrentWordFromDocumentContextResetSuppression:resetSuppression];
|
[self kb_refreshCurrentWordFromDocumentContextResetSuppression:
|
||||||
|
resetSuppression];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)kb_refreshCurrentWordFromDocumentContextResetSuppression:(BOOL)resetSuppression {
|
- (void)kb_refreshCurrentWordFromDocumentContextResetSuppression:
|
||||||
|
(BOOL)resetSuppression {
|
||||||
NSString *context = self.textDocumentProxy.documentContextBeforeInput ?: @"";
|
NSString *context = self.textDocumentProxy.documentContextBeforeInput ?: @"";
|
||||||
NSString *word = [self kb_extractTrailingWordFromContext:context];
|
NSString *word = [self kb_extractTrailingWordFromContext:context];
|
||||||
self.currentWord = word ?: @"";
|
self.currentWord = word ?: @"";
|
||||||
@@ -230,11 +257,15 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)kb_extractTrailingWordFromContext:(NSString *)context {
|
- (NSString *)kb_extractTrailingWordFromContext:(NSString *)context {
|
||||||
if (context.length == 0) { return @""; }
|
if (context.length == 0) {
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
static NSCharacterSet *letters = nil;
|
static NSCharacterSet *letters = nil;
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
letters = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
|
letters = [NSCharacterSet
|
||||||
|
characterSetWithCharactersInString:
|
||||||
|
@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
|
||||||
});
|
});
|
||||||
|
|
||||||
NSInteger idx = (NSInteger)context.length - 1;
|
NSInteger idx = (NSInteger)context.length - 1;
|
||||||
@@ -246,16 +277,22 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
idx -= 1;
|
idx -= 1;
|
||||||
}
|
}
|
||||||
NSUInteger start = (NSUInteger)(idx + 1);
|
NSUInteger start = (NSUInteger)(idx + 1);
|
||||||
if (start >= context.length) { return @""; }
|
if (start >= context.length) {
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
return [context substringFromIndex:start];
|
return [context substringFromIndex:start];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)kb_isAlphabeticString:(NSString *)text {
|
- (BOOL)kb_isAlphabeticString:(NSString *)text {
|
||||||
if (text.length == 0) { return NO; }
|
if (text.length == 0) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
static NSCharacterSet *letters = nil;
|
static NSCharacterSet *letters = nil;
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
letters = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
|
letters = [NSCharacterSet
|
||||||
|
characterSetWithCharactersInString:
|
||||||
|
@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
|
||||||
});
|
});
|
||||||
for (NSUInteger i = 0; i < text.length; i++) {
|
for (NSUInteger i = 0; i < text.length; i++) {
|
||||||
if (![letters characterIsMember:[text characterAtIndex:i]]) {
|
if (![letters characterIsMember:[text characterAtIndex:i]]) {
|
||||||
@@ -275,19 +312,28 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[self.keyBoardMainView kb_setSuggestions:@[]];
|
[self.keyBoardMainView kb_setSuggestions:@[]];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSArray<NSString *> *items = [self.suggestionEngine suggestionsForPrefix:prefix limit:5];
|
NSArray<NSString *> *items =
|
||||||
NSArray<NSString *> *cased = [self kb_applyCaseToSuggestions:items prefix:prefix];
|
[self.suggestionEngine suggestionsForPrefix:prefix limit:5];
|
||||||
|
NSArray<NSString *> *cased = [self kb_applyCaseToSuggestions:items
|
||||||
|
prefix:prefix];
|
||||||
[self.keyBoardMainView kb_setSuggestions:cased];
|
[self.keyBoardMainView kb_setSuggestions:cased];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray<NSString *> *)kb_applyCaseToSuggestions:(NSArray<NSString *> *)items prefix:(NSString *)prefix {
|
- (NSArray<NSString *> *)kb_applyCaseToSuggestions:(NSArray<NSString *> *)items
|
||||||
if (items.count == 0 || prefix.length == 0) { return items; }
|
prefix:(NSString *)prefix {
|
||||||
|
if (items.count == 0 || prefix.length == 0) {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
BOOL allUpper = [prefix isEqualToString:prefix.uppercaseString];
|
BOOL allUpper = [prefix isEqualToString:prefix.uppercaseString];
|
||||||
BOOL firstUpper = [[prefix substringToIndex:1] isEqualToString:[[prefix substringToIndex:1] uppercaseString]];
|
BOOL firstUpper = [[prefix substringToIndex:1]
|
||||||
|
isEqualToString:[[prefix substringToIndex:1] uppercaseString]];
|
||||||
|
|
||||||
if (!allUpper && !firstUpper) { return items; }
|
if (!allUpper && !firstUpper) {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
NSMutableArray<NSString *> *result = [NSMutableArray arrayWithCapacity:items.count];
|
NSMutableArray<NSString *> *result =
|
||||||
|
[NSMutableArray arrayWithCapacity:items.count];
|
||||||
for (NSString *word in items) {
|
for (NSString *word in items) {
|
||||||
if (allUpper) {
|
if (allUpper) {
|
||||||
[result addObject:word.uppercaseString];
|
[result addObject:word.uppercaseString];
|
||||||
@@ -307,13 +353,15 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
self.keyBoardMainView.hidden = show;
|
self.keyBoardMainView.hidden = show;
|
||||||
|
|
||||||
if (show) {
|
if (show) {
|
||||||
[[KBMaiPointReporter sharedReporter] reportPageExposureWithEventName:@"enter_keyboard_function_panel"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportPageExposureWithEventName:@"enter_keyboard_function_panel"
|
||||||
pageId:@"keyboard_function_panel"
|
pageId:@"keyboard_function_panel"
|
||||||
extra:nil
|
extra:nil
|
||||||
completion:nil];
|
completion:nil];
|
||||||
[self hideSubscriptionPanel];
|
[self hideSubscriptionPanel];
|
||||||
} else {
|
} else {
|
||||||
[[KBMaiPointReporter sharedReporter] reportPageExposureWithEventName:@"enter_keyboard_main_panel"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportPageExposureWithEventName:@"enter_keyboard_main_panel"
|
||||||
pageId:@"keyboard_main_panel"
|
pageId:@"keyboard_main_panel"
|
||||||
extra:nil
|
extra:nil
|
||||||
completion:nil];
|
completion:nil];
|
||||||
@@ -330,7 +378,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
/// 显示/隐藏设置页(高度与 keyBoardMainView 一致),右侧滑入/滑出
|
/// 显示/隐藏设置页(高度与 keyBoardMainView 一致),右侧滑入/滑出
|
||||||
- (void)showSettingView:(BOOL)show {
|
- (void)showSettingView:(BOOL)show {
|
||||||
if (show) {
|
if (show) {
|
||||||
[[KBMaiPointReporter sharedReporter] reportPageExposureWithEventName:@"enter_keyboard_settings"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportPageExposureWithEventName:@"enter_keyboard_settings"
|
||||||
pageId:@"keyboard_settings"
|
pageId:@"keyboard_settings"
|
||||||
extra:nil
|
extra:nil
|
||||||
completion:nil];
|
completion:nil];
|
||||||
@@ -342,27 +391,46 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
// 与键盘主视图完全等同的区域,保证高度、宽度一致
|
// 与键盘主视图完全等同的区域,保证高度、宽度一致
|
||||||
make.edges.equalTo(self.contentView);
|
make.edges.equalTo(self.contentView);
|
||||||
}];
|
}];
|
||||||
[self.settingView.backButton addTarget:self action:@selector(onTapSettingsBack) forControlEvents:UIControlEventTouchUpInside];
|
[self.settingView.backButton addTarget:self
|
||||||
|
action:@selector(onTapSettingsBack)
|
||||||
|
forControlEvents:UIControlEventTouchUpInside];
|
||||||
// }
|
// }
|
||||||
[self.contentView bringSubviewToFront:self.settingView];
|
[self.contentView bringSubviewToFront:self.settingView];
|
||||||
// 以 keyBoardMainView 的实际宽度为准,避免首次添加时 self.view 宽度尚未计算
|
// 以 keyBoardMainView 的实际宽度为准,避免首次添加时 self.view 宽度尚未计算
|
||||||
[self.contentView layoutIfNeeded];
|
[self.contentView layoutIfNeeded];
|
||||||
CGFloat w = CGRectGetWidth(self.keyBoardMainView.bounds);
|
CGFloat w = CGRectGetWidth(self.keyBoardMainView.bounds);
|
||||||
if (w <= 0) { w = CGRectGetWidth(self.contentView.bounds); }
|
if (w <= 0) {
|
||||||
if (w <= 0) { w = [self kb_portraitWidth]; }
|
w = CGRectGetWidth(self.contentView.bounds);
|
||||||
|
}
|
||||||
|
if (w <= 0) {
|
||||||
|
w = [self kb_portraitWidth];
|
||||||
|
}
|
||||||
self.settingView.transform = CGAffineTransformMakeTranslation(w, 0);
|
self.settingView.transform = CGAffineTransformMakeTranslation(w, 0);
|
||||||
self.settingView.hidden = NO;
|
self.settingView.hidden = NO;
|
||||||
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
[UIView animateWithDuration:0.25
|
||||||
|
delay:0
|
||||||
|
options:UIViewAnimationOptionCurveEaseOut
|
||||||
|
animations:^{
|
||||||
self.settingView.transform = CGAffineTransformIdentity;
|
self.settingView.transform = CGAffineTransformIdentity;
|
||||||
} completion:nil];
|
}
|
||||||
|
completion:nil];
|
||||||
} else {
|
} else {
|
||||||
if (!self.settingView || self.settingView.hidden) return;
|
if (!self.settingView || self.settingView.hidden)
|
||||||
|
return;
|
||||||
CGFloat w = CGRectGetWidth(self.keyBoardMainView.bounds);
|
CGFloat w = CGRectGetWidth(self.keyBoardMainView.bounds);
|
||||||
if (w <= 0) { w = CGRectGetWidth(self.contentView.bounds); }
|
if (w <= 0) {
|
||||||
if (w <= 0) { w = [self kb_portraitWidth]; }
|
w = CGRectGetWidth(self.contentView.bounds);
|
||||||
[UIView animateWithDuration:0.22 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
|
}
|
||||||
|
if (w <= 0) {
|
||||||
|
w = [self kb_portraitWidth];
|
||||||
|
}
|
||||||
|
[UIView animateWithDuration:0.22
|
||||||
|
delay:0
|
||||||
|
options:UIViewAnimationOptionCurveEaseIn
|
||||||
|
animations:^{
|
||||||
self.settingView.transform = CGAffineTransformMakeTranslation(w, 0);
|
self.settingView.transform = CGAffineTransformMakeTranslation(w, 0);
|
||||||
} completion:^(BOOL finished) {
|
}
|
||||||
|
completion:^(BOOL finished) {
|
||||||
self.settingView.hidden = YES;
|
self.settingView.hidden = YES;
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
@@ -377,15 +445,18 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 点击充值要先判断是否登录
|
// 点击充值要先判断是否登录
|
||||||
// 2) 权限没问题,再判断是否登录:未登录 -> 直接拉起主 App,由主 App 负责完成登录
|
// 2) 权限没问题,再判断是否登录:未登录 -> 直接拉起主 App,由主 App
|
||||||
|
// 负责完成登录
|
||||||
if (!KBAuthManager.shared.isLoggedIn) {
|
if (!KBAuthManager.shared.isLoggedIn) {
|
||||||
NSString *schemeStr = [NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME];
|
NSString *schemeStr =
|
||||||
|
[NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME];
|
||||||
NSURL *scheme = [NSURL URLWithString:schemeStr];
|
NSURL *scheme = [NSURL URLWithString:schemeStr];
|
||||||
// 从当前视图作为起点,通过响应链找到 UIApplication 再调起主 App
|
// 从当前视图作为起点,通过响应链找到 UIApplication 再调起主 App
|
||||||
BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view];
|
BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[[KBMaiPointReporter sharedReporter] reportPageExposureWithEventName:@"enter_keyboard_subscription_panel"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportPageExposureWithEventName:@"enter_keyboard_subscription_panel"
|
||||||
pageId:@"keyboard_subscription_panel"
|
pageId:@"keyboard_subscription_panel"
|
||||||
extra:nil
|
extra:nil
|
||||||
completion:nil];
|
completion:nil];
|
||||||
@@ -402,34 +473,47 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
panel.hidden = NO;
|
panel.hidden = NO;
|
||||||
panel.alpha = 0.0;
|
panel.alpha = 0.0;
|
||||||
CGFloat height = CGRectGetHeight(self.contentView.bounds);
|
CGFloat height = CGRectGetHeight(self.contentView.bounds);
|
||||||
if (height <= 0) { height = 260; }
|
if (height <= 0) {
|
||||||
|
height = 260;
|
||||||
|
}
|
||||||
panel.transform = CGAffineTransformMakeTranslation(0, height);
|
panel.transform = CGAffineTransformMakeTranslation(0, height);
|
||||||
[panel refreshProductsIfNeeded];
|
[panel refreshProductsIfNeeded];
|
||||||
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
[UIView animateWithDuration:0.25
|
||||||
|
delay:0
|
||||||
|
options:UIViewAnimationOptionCurveEaseOut
|
||||||
|
animations:^{
|
||||||
panel.alpha = 1.0;
|
panel.alpha = 1.0;
|
||||||
panel.transform = CGAffineTransformIdentity;
|
panel.transform = CGAffineTransformIdentity;
|
||||||
} completion:nil];
|
}
|
||||||
|
completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)hideSubscriptionPanel {
|
- (void)hideSubscriptionPanel {
|
||||||
if (!self.subscriptionView || self.subscriptionView.hidden) { return; }
|
if (!self.subscriptionView || self.subscriptionView.hidden) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
CGFloat height = CGRectGetHeight(self.subscriptionView.bounds);
|
CGFloat height = CGRectGetHeight(self.subscriptionView.bounds);
|
||||||
if (height <= 0) { height = CGRectGetHeight(self.contentView.bounds); }
|
if (height <= 0) {
|
||||||
|
height = CGRectGetHeight(self.contentView.bounds);
|
||||||
|
}
|
||||||
KBKeyboardSubscriptionView *panel = self.subscriptionView;
|
KBKeyboardSubscriptionView *panel = self.subscriptionView;
|
||||||
[UIView animateWithDuration:0.22 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
|
[UIView animateWithDuration:0.22
|
||||||
|
delay:0
|
||||||
|
options:UIViewAnimationOptionCurveEaseIn
|
||||||
|
animations:^{
|
||||||
panel.alpha = 0.0;
|
panel.alpha = 0.0;
|
||||||
panel.transform = CGAffineTransformMakeTranslation(0, height);
|
panel.transform = CGAffineTransformMakeTranslation(0, height);
|
||||||
} completion:^(BOOL finished) {
|
}
|
||||||
|
completion:^(BOOL finished) {
|
||||||
panel.hidden = YES;
|
panel.hidden = YES;
|
||||||
panel.alpha = 1.0;
|
panel.alpha = 1.0;
|
||||||
panel.transform = CGAffineTransformIdentity;
|
panel.transform = CGAffineTransformIdentity;
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - KBKeyBoardMainViewDelegate
|
// MARK: - KBKeyBoardMainViewDelegate
|
||||||
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didTapKey:(KBKey *)key {
|
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView
|
||||||
|
didTapKey:(KBKey *)key {
|
||||||
switch (key.type) {
|
switch (key.type) {
|
||||||
case KBKeyTypeCharacter: {
|
case KBKeyTypeCharacter: {
|
||||||
[[KBBackspaceUndoManager shared] registerNonClearAction];
|
[[KBBackspaceUndoManager shared] registerNonClearAction];
|
||||||
@@ -439,10 +523,17 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[[KBInputBufferManager shared] appendText:text];
|
[[KBInputBufferManager shared] appendText:text];
|
||||||
} break;
|
} break;
|
||||||
case KBKeyTypeBackspace:
|
case KBKeyTypeBackspace:
|
||||||
[[KBInputBufferManager shared] refreshFromProxyIfPossible:self.textDocumentProxy];
|
[[KBInputBufferManager shared]
|
||||||
[[KBInputBufferManager shared] prepareSnapshotForDeleteWithContextBefore:self.textDocumentProxy.documentContextBeforeInput
|
refreshFromProxyIfPossible:self.textDocumentProxy];
|
||||||
after:self.textDocumentProxy.documentContextAfterInput];
|
[[KBInputBufferManager shared]
|
||||||
[[KBBackspaceUndoManager shared] captureAndDeleteBackwardFromProxy:self.textDocumentProxy count:1];
|
prepareSnapshotForDeleteWithContextBefore:
|
||||||
|
self.textDocumentProxy.documentContextBeforeInput
|
||||||
|
after:
|
||||||
|
self.textDocumentProxy
|
||||||
|
.documentContextAfterInput];
|
||||||
|
[[KBBackspaceUndoManager shared]
|
||||||
|
captureAndDeleteBackwardFromProxy:self.textDocumentProxy
|
||||||
|
count:1];
|
||||||
[self kb_scheduleContextRefreshResetSuppression:NO];
|
[self kb_scheduleContextRefreshResetSuppression:NO];
|
||||||
[[KBInputBufferManager shared] applyHoldDeleteCount:1];
|
[[KBInputBufferManager shared] applyHoldDeleteCount:1];
|
||||||
break;
|
break;
|
||||||
@@ -459,7 +550,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[[KBInputBufferManager shared] appendText:@"\n"];
|
[[KBInputBufferManager shared] appendText:@"\n"];
|
||||||
break;
|
break;
|
||||||
case KBKeyTypeGlobe:
|
case KBKeyTypeGlobe:
|
||||||
[self advanceToNextInputMode]; break;
|
[self advanceToNextInputMode];
|
||||||
|
break;
|
||||||
case KBKeyTypeCustom:
|
case KBKeyTypeCustom:
|
||||||
[[KBBackspaceUndoManager shared] registerNonClearAction];
|
[[KBBackspaceUndoManager shared] registerNonClearAction];
|
||||||
// 点击自定义键切换到功能面板
|
// 点击自定义键切换到功能面板
|
||||||
@@ -473,9 +565,11 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didTapToolActionAtIndex:(NSInteger)index {
|
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView
|
||||||
|
didTapToolActionAtIndex:(NSInteger)index {
|
||||||
NSDictionary *extra = @{@"index" : @(index)};
|
NSDictionary *extra = @{@"index" : @(index)};
|
||||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_toolbar_action"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportClickWithEventName:@"click_keyboard_toolbar_action"
|
||||||
pageId:@"keyboard_main_panel"
|
pageId:@"keyboard_main_panel"
|
||||||
elementId:@"toolbar_action"
|
elementId:@"toolbar_action"
|
||||||
extra:extra
|
extra:extra
|
||||||
@@ -489,7 +583,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyBoardMainViewDidTapSettings:(KBKeyBoardMainView *)keyBoardMainView {
|
- (void)keyBoardMainViewDidTapSettings:(KBKeyBoardMainView *)keyBoardMainView {
|
||||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_settings_btn"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportClickWithEventName:@"click_keyboard_settings_btn"
|
||||||
pageId:@"keyboard_main_panel"
|
pageId:@"keyboard_main_panel"
|
||||||
elementId:@"settings_btn"
|
elementId:@"settings_btn"
|
||||||
extra:nil
|
extra:nil
|
||||||
@@ -497,8 +592,11 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[self showSettingView:YES];
|
[self showSettingView:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didSelectEmoji:(NSString *)emoji {
|
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView
|
||||||
if (emoji.length == 0) { return; }
|
didSelectEmoji:(NSString *)emoji {
|
||||||
|
if (emoji.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
[[KBBackspaceUndoManager shared] registerNonClearAction];
|
[[KBBackspaceUndoManager shared] registerNonClearAction];
|
||||||
[self.textDocumentProxy insertText:emoji];
|
[self.textDocumentProxy insertText:emoji];
|
||||||
[self kb_clearCurrentWord];
|
[self kb_clearCurrentWord];
|
||||||
@@ -506,7 +604,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyBoardMainViewDidTapUndo:(KBKeyBoardMainView *)keyBoardMainView {
|
- (void)keyBoardMainViewDidTapUndo:(KBKeyBoardMainView *)keyBoardMainView {
|
||||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_undo_btn"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportClickWithEventName:@"click_keyboard_undo_btn"
|
||||||
pageId:@"keyboard_main_panel"
|
pageId:@"keyboard_main_panel"
|
||||||
elementId:@"undo_btn"
|
elementId:@"undo_btn"
|
||||||
extra:nil
|
extra:nil
|
||||||
@@ -515,8 +614,10 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[self kb_scheduleContextRefreshResetSuppression:YES];
|
[self kb_scheduleContextRefreshResetSuppression:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyBoardMainViewDidTapEmojiSearch:(KBKeyBoardMainView *)keyBoardMainView {
|
- (void)keyBoardMainViewDidTapEmojiSearch:
|
||||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_emoji_search_btn"
|
(KBKeyBoardMainView *)keyBoardMainView {
|
||||||
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportClickWithEventName:@"click_keyboard_emoji_search_btn"
|
||||||
pageId:@"keyboard_main_panel"
|
pageId:@"keyboard_main_panel"
|
||||||
elementId:@"emoji_search_btn"
|
elementId:@"emoji_search_btn"
|
||||||
extra:nil
|
extra:nil
|
||||||
@@ -524,10 +625,14 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[KBHUD showInfo:KBLocalized(@"Search coming soon")];
|
[KBHUD showInfo:KBLocalized(@"Search coming soon")];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didSelectSuggestion:(NSString *)suggestion {
|
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView
|
||||||
if (suggestion.length == 0) { return; }
|
didSelectSuggestion:(NSString *)suggestion {
|
||||||
|
if (suggestion.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
NSDictionary *extra = @{@"suggestion_len" : @(suggestion.length)};
|
NSDictionary *extra = @{@"suggestion_len" : @(suggestion.length)};
|
||||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_suggestion_item"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportClickWithEventName:@"click_keyboard_suggestion_item"
|
||||||
pageId:@"keyboard_main_panel"
|
pageId:@"keyboard_main_panel"
|
||||||
elementId:@"suggestion_item"
|
elementId:@"suggestion_item"
|
||||||
extra:extra
|
extra:extra
|
||||||
@@ -544,30 +649,36 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[self.suggestionEngine recordSelection:suggestion];
|
[self.suggestionEngine recordSelection:suggestion];
|
||||||
self.suppressSuggestions = YES;
|
self.suppressSuggestions = YES;
|
||||||
[self.keyBoardMainView kb_setSuggestions:@[]];
|
[self.keyBoardMainView kb_setSuggestions:@[]];
|
||||||
[[KBInputBufferManager shared] replaceTailWithText:suggestion deleteCount:current.length];
|
[[KBInputBufferManager shared] replaceTailWithText:suggestion
|
||||||
|
deleteCount:current.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - KBFunctionViewDelegate
|
// MARK: - KBFunctionViewDelegate
|
||||||
- (void)functionView:(KBFunctionView *)functionView didTapToolActionAtIndex:(NSInteger)index {
|
- (void)functionView:(KBFunctionView *)functionView
|
||||||
|
didTapToolActionAtIndex:(NSInteger)index {
|
||||||
// 需求:当 index == 0 时,切回键盘主视图
|
// 需求:当 index == 0 时,切回键盘主视图
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
[self showFunctionPanel:NO];
|
[self showFunctionPanel:NO];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
- (void)functionView:(KBFunctionView *_Nullable)functionView didRightTapToolActionAtIndex:(NSInteger)index{
|
- (void)functionView:(KBFunctionView *_Nullable)functionView
|
||||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_function_right_action"
|
didRightTapToolActionAtIndex:(NSInteger)index {
|
||||||
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportClickWithEventName:@"click_keyboard_function_right_action"
|
||||||
pageId:@"keyboard_function_panel"
|
pageId:@"keyboard_function_panel"
|
||||||
elementId:@"right_action"
|
elementId:@"right_action"
|
||||||
extra:@{@"action" : @"login_or_recharge"}
|
extra:@{@"action" : @"login_or_recharge"}
|
||||||
completion:nil];
|
completion:nil];
|
||||||
if (!KBAuthManager.shared.isLoggedIn) {
|
if (!KBAuthManager.shared.isLoggedIn) {
|
||||||
NSString *schemeStr = [NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME];
|
NSString *schemeStr =
|
||||||
|
[NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME];
|
||||||
NSURL *scheme = [NSURL URLWithString:schemeStr];
|
NSURL *scheme = [NSURL URLWithString:schemeStr];
|
||||||
// 从当前视图作为起点,通过响应链找到 UIApplication 再调起主 App
|
// 从当前视图作为起点,通过响应链找到 UIApplication 再调起主 App
|
||||||
BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view];
|
BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSString *schemeStr = [NSString stringWithFormat:@"%@://recharge?src=keyboard", KB_APP_SCHEME];
|
NSString *schemeStr =
|
||||||
|
[NSString stringWithFormat:@"%@://recharge?src=keyboard", KB_APP_SCHEME];
|
||||||
NSURL *scheme = [NSURL URLWithString:schemeStr];
|
NSURL *scheme = [NSURL URLWithString:schemeStr];
|
||||||
//
|
//
|
||||||
// if (!ul && !scheme) { return; }
|
// if (!ul && !scheme) { return; }
|
||||||
@@ -589,7 +700,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
#pragma mark - KBKeyboardSubscriptionViewDelegate
|
#pragma mark - KBKeyboardSubscriptionViewDelegate
|
||||||
|
|
||||||
- (void)subscriptionViewDidTapClose:(KBKeyboardSubscriptionView *)view {
|
- (void)subscriptionViewDidTapClose:(KBKeyboardSubscriptionView *)view {
|
||||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_subscription_close_btn"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportClickWithEventName:@"click_keyboard_subscription_close_btn"
|
||||||
pageId:@"keyboard_subscription_panel"
|
pageId:@"keyboard_subscription_panel"
|
||||||
elementId:@"close_btn"
|
elementId:@"close_btn"
|
||||||
extra:nil
|
extra:nil
|
||||||
@@ -597,12 +709,15 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[self hideSubscriptionPanel];
|
[self hideSubscriptionPanel];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)subscriptionView:(KBKeyboardSubscriptionView *)view didTapPurchaseForProduct:(KBKeyboardSubscriptionProduct *)product {
|
- (void)subscriptionView:(KBKeyboardSubscriptionView *)view
|
||||||
|
didTapPurchaseForProduct:(KBKeyboardSubscriptionProduct *)product {
|
||||||
NSMutableDictionary *extra = [NSMutableDictionary dictionary];
|
NSMutableDictionary *extra = [NSMutableDictionary dictionary];
|
||||||
if ([product.productId isKindOfClass:NSString.class] && product.productId.length > 0) {
|
if ([product.productId isKindOfClass:NSString.class] &&
|
||||||
|
product.productId.length > 0) {
|
||||||
extra[@"product_id"] = product.productId;
|
extra[@"product_id"] = product.productId;
|
||||||
}
|
}
|
||||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_subscription_product_btn"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportClickWithEventName:@"click_keyboard_subscription_product_btn"
|
||||||
pageId:@"keyboard_subscription_panel"
|
pageId:@"keyboard_subscription_panel"
|
||||||
elementId:@"product_btn"
|
elementId:@"product_btn"
|
||||||
extra:extra.copy
|
extra:extra.copy
|
||||||
@@ -645,43 +760,52 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
return _subscriptionView;
|
return _subscriptionView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Actions
|
#pragma mark - Actions
|
||||||
|
|
||||||
- (void)kb_openRechargeForProduct:(KBKeyboardSubscriptionProduct *)product {
|
- (void)kb_openRechargeForProduct:(KBKeyboardSubscriptionProduct *)product {
|
||||||
if (![product isKindOfClass:KBKeyboardSubscriptionProduct.class] || product.productId.length == 0) {
|
if (![product isKindOfClass:KBKeyboardSubscriptionProduct.class] ||
|
||||||
|
product.productId.length == 0) {
|
||||||
[KBHUD showInfo:KBLocalized(@"Product unavailable")];
|
[KBHUD showInfo:KBLocalized(@"Product unavailable")];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSString *encodedId = [self.class kb_urlEncodedString:product.productId];
|
NSString *encodedId = [self.class kb_urlEncodedString:product.productId];
|
||||||
NSString *title = [product displayTitle];
|
NSString *title = [product displayTitle];
|
||||||
NSString *encodedTitle = [self.class kb_urlEncodedString:title];
|
NSString *encodedTitle = [self.class kb_urlEncodedString:title];
|
||||||
NSMutableArray<NSString *> *params = [NSMutableArray arrayWithObjects:@"autoPay=1", @"prefill=1", nil];
|
NSMutableArray<NSString *> *params =
|
||||||
|
[NSMutableArray arrayWithObjects:@"autoPay=1", @"prefill=1", nil];
|
||||||
if (encodedId.length) {
|
if (encodedId.length) {
|
||||||
[params addObject:[NSString stringWithFormat:@"productId=%@", encodedId]];
|
[params addObject:[NSString stringWithFormat:@"productId=%@", encodedId]];
|
||||||
}
|
}
|
||||||
if (encodedTitle.length) {
|
if (encodedTitle.length) {
|
||||||
[params addObject:[NSString stringWithFormat:@"productTitle=%@", encodedTitle]];
|
[params
|
||||||
|
addObject:[NSString stringWithFormat:@"productTitle=%@", encodedTitle]];
|
||||||
}
|
}
|
||||||
NSString *query = [params componentsJoinedByString:@"&"];
|
NSString *query = [params componentsJoinedByString:@"&"];
|
||||||
NSString *urlString = [NSString stringWithFormat:@"%@://recharge?src=keyboard&%@", KB_APP_SCHEME, query];
|
NSString *urlString = [NSString
|
||||||
|
stringWithFormat:@"%@://recharge?src=keyboard&%@", KB_APP_SCHEME, query];
|
||||||
NSURL *scheme = [NSURL URLWithString:urlString];
|
NSURL *scheme = [NSURL URLWithString:urlString];
|
||||||
BOOL success = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view];
|
BOOL success = [KBHostAppLauncher openHostAppURL:scheme
|
||||||
|
fromResponder:self.view];
|
||||||
if (!success) {
|
if (!success) {
|
||||||
[KBHUD showInfo:KBLocalized(@"Please open the App to finish purchase")];
|
[KBHUD showInfo:KBLocalized(@"Please open the App to finish purchase")];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSString *)kb_urlEncodedString:(NSString *)value {
|
+ (NSString *)kb_urlEncodedString:(NSString *)value {
|
||||||
if (value.length == 0) { return @""; }
|
if (value.length == 0) {
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
NSString *reserved = @"!*'();:@&=+$,/?%#[]";
|
NSString *reserved = @"!*'();:@&=+$,/?%#[]";
|
||||||
NSMutableCharacterSet *allowed = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
|
NSMutableCharacterSet *allowed =
|
||||||
|
[[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
|
||||||
[allowed removeCharactersInString:reserved];
|
[allowed removeCharactersInString:reserved];
|
||||||
return [value stringByAddingPercentEncodingWithAllowedCharacters:allowed] ?: @"";
|
return [value stringByAddingPercentEncodingWithAllowedCharacters:allowed]
|
||||||
|
?: @"";
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)onTapSettingsBack {
|
- (void)onTapSettingsBack {
|
||||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_settings_back_btn"
|
[[KBMaiPointReporter sharedReporter]
|
||||||
|
reportClickWithEventName:@"click_keyboard_settings_back_btn"
|
||||||
pageId:@"keyboard_settings"
|
pageId:@"keyboard_settings"
|
||||||
elementId:@"back_btn"
|
elementId:@"back_btn"
|
||||||
extra:nil
|
extra:nil
|
||||||
@@ -690,14 +814,14 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(),
|
CFNotificationCenterRemoveObserver(
|
||||||
|
CFNotificationCenterGetDarwinNotifyCenter(),
|
||||||
(__bridge const void *)(self),
|
(__bridge const void *)(self),
|
||||||
(__bridge CFStringRef)KBDarwinSkinInstallRequestNotification,
|
(__bridge CFStringRef)KBDarwinSkinInstallRequestNotification, NULL);
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 当键盘第一次显示时,尝试唤起主 App 以提示登录(由主 App
|
||||||
// 当键盘第一次显示时,尝试唤起主 App 以提示登录(由主 App 决定是否真的弹登录)。
|
// 决定是否真的弹登录)。
|
||||||
- (void)viewDidAppear:(BOOL)animated {
|
- (void)viewDidAppear:(BOOL)animated {
|
||||||
[super viewDidAppear:animated];
|
[super viewDidAppear:animated];
|
||||||
// if (!_kb_didTriggerLoginDeepLinkOnce) {
|
// if (!_kb_didTriggerLoginDeepLinkOnce) {
|
||||||
@@ -714,22 +838,29 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
[self kb_updateKeyboardLayoutIfNeeded];
|
[self kb_updateKeyboardLayoutIfNeeded];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
- (void)viewWillTransitionToSize:(CGSize)size
|
||||||
|
withTransitionCoordinator:
|
||||||
|
(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
[coordinator
|
||||||
|
animateAlongsideTransition:^(
|
||||||
|
id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||||
[weakSelf kb_updateKeyboardLayoutIfNeeded];
|
[weakSelf kb_updateKeyboardLayoutIfNeeded];
|
||||||
} completion:^(__unused id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
}
|
||||||
|
completion:^(
|
||||||
|
__unused id<
|
||||||
|
UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||||
[weakSelf kb_updateKeyboardLayoutIfNeeded];
|
[weakSelf kb_updateKeyboardLayoutIfNeeded];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
//- (void)kb_tryOpenContainerForLoginIfNeeded {
|
//- (void)kb_tryOpenContainerForLoginIfNeeded {
|
||||||
// // 使用与主 App 一致的自定义 Scheme
|
// // 使用与主 App 一致的自定义 Scheme
|
||||||
// NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@@//login?src=keyboard", KB_APP_SCHEME]];
|
// NSURL *url = [NSURL URLWithString:[NSString
|
||||||
// if (!url) return;
|
// stringWithFormat:@"%@@//login?src=keyboard", KB_APP_SCHEME]]; if (!url)
|
||||||
// KBWeakSelf
|
// return; KBWeakSelf [self.extensionContext openURL:url
|
||||||
// [self.extensionContext openURL:url completionHandler:^(__unused BOOL success) {
|
// completionHandler:^(__unused BOOL success) {
|
||||||
// // 即使失败也不重复尝试;避免打扰。
|
// // 即使失败也不重复尝试;避免打扰。
|
||||||
// __unused typeof(weakSelf) selfStrong = weakSelf;
|
// __unused typeof(weakSelf) selfStrong = weakSelf;
|
||||||
// }];
|
// }];
|
||||||
@@ -740,8 +871,48 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
- (void)kb_applyTheme {
|
- (void)kb_applyTheme {
|
||||||
KBSkinTheme *t = [KBSkinManager shared].current;
|
KBSkinTheme *t = [KBSkinManager shared].current;
|
||||||
UIImage *img = [[KBSkinManager shared] currentBackgroundImage];
|
UIImage *img = [[KBSkinManager shared] currentBackgroundImage];
|
||||||
if ([self kb_isDefaultKeyboardTheme:t]) {
|
BOOL isDefaultTheme = [self kb_isDefaultKeyboardTheme:t];
|
||||||
|
BOOL isDarkMode = [self kb_isDarkModeActive];
|
||||||
CGSize size = self.bgImageView.bounds.size;
|
CGSize size = self.bgImageView.bounds.size;
|
||||||
|
if (isDefaultTheme) {
|
||||||
|
if (isDarkMode) {
|
||||||
|
// 暗黑模式:直接使用背景色,不使用图片渲染
|
||||||
|
// 这样可以避免图片渲染时的色彩空间转换导致颜色不一致
|
||||||
|
img = nil;
|
||||||
|
self.bgImageView.image = nil;
|
||||||
|
// 使用与系统键盘底部完全相同的颜色
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
// iOS 系统键盘使用的实际颜色 (RGB: 44, 44, 46 in sRGB, 或 #2C2C2E)
|
||||||
|
// 但为了完美匹配,我们使用动态颜色并直接设置为背景
|
||||||
|
UIColor *kbBgColor =
|
||||||
|
[UIColor colorWithDynamicProvider:^UIColor *_Nonnull(
|
||||||
|
UITraitCollection *_Nonnull traitCollection) {
|
||||||
|
if (traitCollection.userInterfaceStyle ==
|
||||||
|
UIUserInterfaceStyleDark) {
|
||||||
|
// 暗黑模式下系统键盘实际背景色
|
||||||
|
return [UIColor colorWithRed:43.0 / 255.0
|
||||||
|
green:43.0 / 255.0
|
||||||
|
blue:43.0 / 255.0
|
||||||
|
alpha:1.0];
|
||||||
|
} else {
|
||||||
|
return [UIColor colorWithRed:209.0 / 255.0
|
||||||
|
green:211.0 / 255.0
|
||||||
|
blue:219.0 / 255.0
|
||||||
|
alpha:1.0];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
self.contentView.backgroundColor = kbBgColor;
|
||||||
|
self.bgImageView.backgroundColor = kbBgColor;
|
||||||
|
} else {
|
||||||
|
UIColor *darkColor = [UIColor colorWithRed:43.0 / 255.0
|
||||||
|
green:43.0 / 255.0
|
||||||
|
blue:43.0 / 255.0
|
||||||
|
alpha:1.0];
|
||||||
|
self.contentView.backgroundColor = darkColor;
|
||||||
|
self.bgImageView.backgroundColor = darkColor;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 浅色模式:使用渐变图片
|
||||||
if (size.width <= 0 || size.height <= 0) {
|
if (size.width <= 0 || size.height <= 0) {
|
||||||
[self.view layoutIfNeeded];
|
[self.view layoutIfNeeded];
|
||||||
size = self.bgImageView.bounds.size;
|
size = self.bgImageView.bounds.size;
|
||||||
@@ -752,15 +923,24 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
if (size.width <= 0 || size.height <= 0) {
|
if (size.width <= 0 || size.height <= 0) {
|
||||||
size = [UIScreen mainScreen].bounds.size;
|
size = [UIScreen mainScreen].bounds.size;
|
||||||
}
|
}
|
||||||
img = [self kb_defaultGradientImageWithSize:size];
|
UIColor *topColor = [UIColor colorWithHex:0xDEDFE4];
|
||||||
|
UIColor *bottomColor = [UIColor colorWithHex:0xD1D3DB];
|
||||||
|
img = [self kb_defaultGradientImageWithSize:size
|
||||||
|
topColor:topColor
|
||||||
|
bottomColor:bottomColor];
|
||||||
|
self.contentView.backgroundColor = [UIColor clearColor];
|
||||||
|
self.bgImageView.backgroundColor = [UIColor clearColor];
|
||||||
|
}
|
||||||
|
NSLog(@"===");
|
||||||
|
} else {
|
||||||
|
// 自定义皮肤:清除背景色,使用皮肤图片
|
||||||
|
self.contentView.backgroundColor = [UIColor clearColor];
|
||||||
|
self.bgImageView.backgroundColor = [UIColor clearColor];
|
||||||
}
|
}
|
||||||
NSLog(@"⌨️[Keyboard] apply theme id=%@ hasBg=%d", t.skinId, (img != nil));
|
NSLog(@"⌨️[Keyboard] apply theme id=%@ hasBg=%d", t.skinId, (img != nil));
|
||||||
[self kb_logSkinDiagnosticsWithTheme:t backgroundImage:img];
|
[self kb_logSkinDiagnosticsWithTheme:t backgroundImage:img];
|
||||||
self.bgImageView.image = img;
|
self.bgImageView.image = img;
|
||||||
BOOL hasImg = (img != nil);
|
BOOL hasImg = (img != nil);
|
||||||
self.view.backgroundColor = hasImg ? [UIColor clearColor] : t.keyboardBackground;
|
|
||||||
self.contentView.backgroundColor = hasImg ? [UIColor clearColor] : t.keyboardBackground;
|
|
||||||
self.keyBoardMainView.backgroundColor = hasImg ? [UIColor clearColor] : t.keyboardBackground;
|
|
||||||
// 触发键区按主题重绘
|
// 触发键区按主题重绘
|
||||||
if ([self.keyBoardMainView respondsToSelector:@selector(kb_applyTheme)]) {
|
if ([self.keyBoardMainView respondsToSelector:@selector(kb_applyTheme)]) {
|
||||||
// method declared in KBKeyBoardMainView.h
|
// method declared in KBKeyBoardMainView.h
|
||||||
@@ -796,23 +976,39 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)kb_defaultSkinIdForCurrentStyle {
|
- (NSString *)kb_defaultSkinIdForCurrentStyle {
|
||||||
return [self kb_isDarkModeActive] ? kKBDefaultSkinIdDark : kKBDefaultSkinIdLight;
|
return [self kb_isDarkModeActive] ? kKBDefaultSkinIdDark
|
||||||
|
: kKBDefaultSkinIdLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)kb_defaultSkinZipNameForCurrentStyle {
|
- (NSString *)kb_defaultSkinZipNameForCurrentStyle {
|
||||||
return [self kb_isDarkModeActive] ? kKBDefaultSkinZipNameDark : kKBDefaultSkinZipNameLight;
|
return [self kb_isDarkModeActive] ? kKBDefaultSkinZipNameDark
|
||||||
|
: kKBDefaultSkinZipNameLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIImage *)kb_defaultGradientImageWithSize:(CGSize)size
|
||||||
|
topColor:(UIColor *)topColor
|
||||||
|
bottomColor:(UIColor *)bottomColor {
|
||||||
|
if (size.width <= 0 || size.height <= 0) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将动态颜色解析为当前 trait collection 下的具体颜色值
|
||||||
|
// 否则在 UIGraphicsBeginImageContextWithOptions 中渲染时会使用默认的浅色模式
|
||||||
|
UIColor *resolvedTopColor = topColor;
|
||||||
|
UIColor *resolvedBottomColor = bottomColor;
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
resolvedTopColor =
|
||||||
|
[topColor resolvedColorWithTraitCollection:self.traitCollection];
|
||||||
|
resolvedBottomColor =
|
||||||
|
[bottomColor resolvedColorWithTraitCollection:self.traitCollection];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIImage *)kb_defaultGradientImageWithSize:(CGSize)size {
|
|
||||||
if (size.width <= 0 || size.height <= 0) { return nil; }
|
|
||||||
CAGradientLayer *layer = [CAGradientLayer layer];
|
CAGradientLayer *layer = [CAGradientLayer layer];
|
||||||
layer.frame = CGRectMake(0, 0, size.width, size.height);
|
layer.frame = CGRectMake(0, 0, size.width, size.height);
|
||||||
layer.startPoint = CGPointMake(0.5, 0.0);
|
layer.startPoint = CGPointMake(0.5, 0.0);
|
||||||
layer.endPoint = CGPointMake(0.5, 1.0);
|
layer.endPoint = CGPointMake(0.5, 1.0);
|
||||||
layer.colors = @[
|
layer.colors =
|
||||||
(id)[UIColor colorWithHex:0xDEDFE4].CGColor,
|
@[ (id)resolvedTopColor.CGColor, (id)resolvedBottomColor.CGColor ];
|
||||||
(id)[UIColor colorWithHex:0xD1D3DB].CGColor
|
|
||||||
];
|
|
||||||
|
|
||||||
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
|
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
|
||||||
[layer renderInContext:UIGraphicsGetCurrentContext()];
|
[layer renderInContext:UIGraphicsGetCurrentContext()];
|
||||||
@@ -827,11 +1023,14 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
NSString *skinId = theme.skinId ?: @"";
|
NSString *skinId = theme.skinId ?: @"";
|
||||||
NSString *name = theme.name ?: @"";
|
NSString *name = theme.name ?: @"";
|
||||||
NSMutableArray<NSString *> *roots = [NSMutableArray array];
|
NSMutableArray<NSString *> *roots = [NSMutableArray array];
|
||||||
NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup];
|
NSURL *containerURL = [[NSFileManager defaultManager]
|
||||||
|
containerURLForSecurityApplicationGroupIdentifier:AppGroup];
|
||||||
if (containerURL.path.length > 0) {
|
if (containerURL.path.length > 0) {
|
||||||
[roots addObject:containerURL.path];
|
[roots addObject:containerURL.path];
|
||||||
}
|
}
|
||||||
NSString *cacheRoot = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
|
NSString *cacheRoot = NSSearchPathForDirectoriesInDomains(
|
||||||
|
NSCachesDirectory, NSUserDomainMask, YES)
|
||||||
|
.firstObject;
|
||||||
if (cacheRoot.length > 0) {
|
if (cacheRoot.length > 0) {
|
||||||
[roots addObject:cacheRoot];
|
[roots addObject:cacheRoot];
|
||||||
}
|
}
|
||||||
@@ -844,36 +1043,58 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
iconsDir = [iconsDir stringByAppendingPathComponent:@"icons"];
|
iconsDir = [iconsDir stringByAppendingPathComponent:@"icons"];
|
||||||
BOOL isDir = NO;
|
BOOL isDir = NO;
|
||||||
BOOL exists = [fm fileExistsAtPath:iconsDir isDirectory:&isDir] && isDir;
|
BOOL exists = [fm fileExistsAtPath:iconsDir isDirectory:&isDir] && isDir;
|
||||||
NSArray *contents = exists ? [fm contentsOfDirectoryAtPath:iconsDir error:nil] : nil;
|
NSArray *contents =
|
||||||
|
exists ? [fm contentsOfDirectoryAtPath:iconsDir error:nil] : nil;
|
||||||
NSUInteger count = contents.count;
|
NSUInteger count = contents.count;
|
||||||
BOOL hasQ = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_q.png"]];
|
BOOL hasQ =
|
||||||
BOOL hasQUp = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_q_up.png"]];
|
exists &&
|
||||||
BOOL hasDel = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_del.png"]];
|
[fm fileExistsAtPath:[iconsDir
|
||||||
BOOL hasShift = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_up.png"]];
|
stringByAppendingPathComponent:@"key_q.png"]];
|
||||||
BOOL hasShiftUpper = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_up_upper.png"]];
|
BOOL hasQUp =
|
||||||
NSString *line = [NSString stringWithFormat:@"root=%@ icons=%@ exist=%d count=%tu key_q=%d key_q_up=%d key_del=%d key_up=%d key_up_upper=%d",
|
exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:
|
||||||
root, iconsDir, exists, count, hasQ, hasQUp, hasDel, hasShift, hasShiftUpper];
|
@"key_q_up.png"]];
|
||||||
|
BOOL hasDel =
|
||||||
|
exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:
|
||||||
|
@"key_del.png"]];
|
||||||
|
BOOL hasShift =
|
||||||
|
exists &&
|
||||||
|
[fm fileExistsAtPath:[iconsDir
|
||||||
|
stringByAppendingPathComponent:@"key_up.png"]];
|
||||||
|
BOOL hasShiftUpper =
|
||||||
|
exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:
|
||||||
|
@"key_up_upper.png"]];
|
||||||
|
NSString *line = [NSString
|
||||||
|
stringWithFormat:@"root=%@ icons=%@ exist=%d count=%tu key_q=%d "
|
||||||
|
@"key_q_up=%d key_del=%d key_up=%d key_up_upper=%d",
|
||||||
|
root, iconsDir, exists, count, hasQ, hasQUp, hasDel,
|
||||||
|
hasShift, hasShiftUpper];
|
||||||
[lines addObject:line];
|
[lines addObject:line];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"[Keyboard] theme id=%@ name=%@ hasBg=%d\n%@",
|
NSLog(@"[Keyboard] theme id=%@ name=%@ hasBg=%d\n%@", skinId, name,
|
||||||
skinId, name, (image != nil), [lines componentsJoinedByString:@"\n"]);
|
(image != nil), [lines componentsJoinedByString:@"\n"]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)kb_consumePendingShopSkin {
|
- (void)kb_consumePendingShopSkin {
|
||||||
KBWeakSelf
|
KBWeakSelf [KBSkinInstallBridge
|
||||||
[KBSkinInstallBridge consumePendingRequestFromBundle:NSBundle.mainBundle
|
consumePendingRequestFromBundle:NSBundle.mainBundle
|
||||||
completion:^(BOOL success, NSError * _Nullable error) {
|
completion:^(BOOL success,
|
||||||
|
NSError *_Nullable error) {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
if (error) {
|
if (error) {
|
||||||
NSLog(@"[Keyboard] skin request failed: %@", error);
|
NSLog(@"[Keyboard] skin request failed: %@",
|
||||||
[KBHUD showInfo:KBLocalized(@"皮肤资源准备失败,请稍后再试")];
|
error);
|
||||||
|
[KBHUD
|
||||||
|
showInfo:
|
||||||
|
KBLocalized(
|
||||||
|
@"皮肤资源准备失败,请稍后再试")];
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[weakSelf kb_applyTheme];
|
[weakSelf kb_applyTheme];
|
||||||
[KBHUD showInfo:KBLocalized(@"皮肤已更新,立即体验吧")];
|
[KBHUD showInfo:KBLocalized(
|
||||||
|
@"皮肤已更新,立即体验吧")];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -886,7 +1107,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NSString *currentId = [KBSkinManager shared].current.skinId ?: @"";
|
NSString *currentId = [KBSkinManager shared].current.skinId ?: @"";
|
||||||
BOOL isDefault = (currentId.length == 0 || [currentId isEqualToString:@"default"]);
|
BOOL isDefault =
|
||||||
|
(currentId.length == 0 || [currentId isEqualToString:@"default"]);
|
||||||
BOOL isLightDefault = [currentId isEqualToString:kKBDefaultSkinIdLight];
|
BOOL isLightDefault = [currentId isEqualToString:kKBDefaultSkinIdLight];
|
||||||
BOOL isDarkDefault = [currentId isEqualToString:kKBDefaultSkinIdDark];
|
BOOL isDarkDefault = [currentId isEqualToString:kKBDefaultSkinIdDark];
|
||||||
if (!isDefault && !isLightDefault && !isDarkDefault) {
|
if (!isDefault && !isLightDefault && !isDarkDefault) {
|
||||||
@@ -895,10 +1117,13 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
NSString *targetId = [self kb_defaultSkinIdForCurrentStyle];
|
NSString *targetId = [self kb_defaultSkinIdForCurrentStyle];
|
||||||
NSString *targetZip = [self kb_defaultSkinZipNameForCurrentStyle];
|
NSString *targetZip = [self kb_defaultSkinZipNameForCurrentStyle];
|
||||||
if (currentId.length > 0 && [currentId isEqualToString:targetId]) { return; }
|
if (currentId.length > 0 && [currentId isEqualToString:targetId]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NSError *applyError = nil;
|
NSError *applyError = nil;
|
||||||
if ([KBSkinInstallBridge applyInstalledSkinWithId:targetId error:&applyError]) {
|
if ([KBSkinInstallBridge applyInstalledSkinWithId:targetId
|
||||||
|
error:&applyError]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,8 +1131,10 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
name:targetId
|
name:targetId
|
||||||
zipName:targetZip
|
zipName:targetZip
|
||||||
iconShortNames:nil];
|
iconShortNames:nil];
|
||||||
[KBSkinInstallBridge consumePendingRequestFromBundle:NSBundle.mainBundle
|
[KBSkinInstallBridge
|
||||||
completion:^(__unused BOOL success, __unused NSError * _Nullable error) {
|
consumePendingRequestFromBundle:NSBundle.mainBundle
|
||||||
|
completion:^(__unused BOOL success,
|
||||||
|
__unused NSError *_Nullable error){
|
||||||
// 已通过通知触发主题刷新,这里无需额外处理
|
// 已通过通知触发主题刷新,这里无需额外处理
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
@@ -920,7 +1147,9 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (CGFloat)kb_keyboardHeightForWidth:(CGFloat)width {
|
- (CGFloat)kb_keyboardHeightForWidth:(CGFloat)width {
|
||||||
if (width <= 0) { width = KB_DESIGN_WIDTH; }
|
if (width <= 0) {
|
||||||
|
width = KB_DESIGN_WIDTH;
|
||||||
|
}
|
||||||
return kKBKeyboardBaseHeight * (width / KB_DESIGN_WIDTH);
|
return kKBKeyboardBaseHeight * (width / KB_DESIGN_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,8 +1165,10 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOL widthChanged = (fabs(self.kb_lastPortraitWidth - portraitWidth) >= 0.5);
|
BOOL widthChanged = (fabs(self.kb_lastPortraitWidth - portraitWidth) >= 0.5);
|
||||||
BOOL heightChanged = (fabs(self.kb_lastKeyboardHeight - keyboardHeight) >= 0.5);
|
BOOL heightChanged =
|
||||||
if (!widthChanged && !heightChanged && containerWidth > 0 && self.kb_widthConstraint.constant == containerWidth) {
|
(fabs(self.kb_lastKeyboardHeight - keyboardHeight) >= 0.5);
|
||||||
|
if (!widthChanged && !heightChanged && containerWidth > 0 &&
|
||||||
|
self.kb_widthConstraint.constant == containerWidth) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.kb_lastPortraitWidth = portraitWidth;
|
self.kb_lastPortraitWidth = portraitWidth;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
// - 兼容后端“/t”作为分段标记:可自动替换为制表符“\t”
|
// - 兼容后端“/t”作为分段标记:可自动替换为制表符“\t”
|
||||||
// - 首段去首个“\t”:若首次正文以一个制表符起始(允许前导空白),可只移除“一个”\t
|
// - 首段去首个“\t”:若首次正文以一个制表符起始(允许前导空白),可只移除“一个”\t
|
||||||
//
|
//
|
||||||
|
// 暂未使用
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
//
|
//
|
||||||
// Created by Mac on 2025/11/12.
|
// Created by Mac on 2025/11/12.
|
||||||
//
|
//
|
||||||
|
// 暂未使用
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -255,11 +255,8 @@
|
|||||||
|
|
||||||
- (void)kb_applyTheme {
|
- (void)kb_applyTheme {
|
||||||
KBSkinManager *mgr = [KBSkinManager shared];
|
KBSkinManager *mgr = [KBSkinManager shared];
|
||||||
BOOL hasImg = ([mgr currentBackgroundImage] != nil);
|
self.backgroundColor = [UIColor clearColor];
|
||||||
// UIColor *bg = mgr.current.keyboardBackground;
|
self.keyboardView.backgroundColor = [UIColor clearColor];
|
||||||
UIColor *bg = [UIColor colorWithHex:0xD1D3DB];
|
|
||||||
self.backgroundColor = hasImg ? [UIColor clearColor] : bg;
|
|
||||||
self.keyboardView.backgroundColor = hasImg ? [UIColor clearColor] : bg;
|
|
||||||
if ([self.topBar respondsToSelector:@selector(kb_applyTheme)]) {
|
if ([self.topBar respondsToSelector:@selector(kb_applyTheme)]) {
|
||||||
[self.topBar kb_applyTheme];
|
[self.topBar kb_applyTheme];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,10 @@
|
|||||||
if (CGRectGetHeight(bounds) <= 0 || CGRectGetWidth(bounds) <= 0) {
|
if (CGRectGetHeight(bounds) <= 0 || CGRectGetWidth(bounds) <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 有皮肤图时,强制隐藏文字,避免图标与文本叠加
|
||||||
|
if (self.iconView.image != nil) {
|
||||||
|
self.titleLabel.hidden = YES;
|
||||||
|
}
|
||||||
self.bottomShadowLayer.frame = CGRectMake(0,
|
self.bottomShadowLayer.frame = CGRectMake(0,
|
||||||
CGRectGetHeight(bounds) - shadowHeight,
|
CGRectGetHeight(bounds) - shadowHeight,
|
||||||
CGRectGetWidth(bounds),
|
CGRectGetWidth(bounds),
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ static const CGFloat kKBLettersRow2EdgeSpacerMultiplier = 0.5;
|
|||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame {
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
if (self = [super initWithFrame:frame]) {
|
if (self = [super initWithFrame:frame]) {
|
||||||
self.backgroundColor = [KBSkinManager shared].current.keyboardBackground;
|
self.backgroundColor = [UIColor clearColor];
|
||||||
_layoutStyle = KBKeyboardLayoutStyleLetters;
|
_layoutStyle = KBKeyboardLayoutStyleLetters;
|
||||||
// 默认小写:与需求一致,初始不开启 Shift
|
// 默认小写:与需求一致,初始不开启 Shift
|
||||||
_shiftOn = NO;
|
_shiftOn = NO;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
#define API_SUBSCRIPTION_PRODUCT_LIST @"/products/subscription/list" // 查询订阅商品列表
|
#define API_SUBSCRIPTION_PRODUCT_LIST @"/products/subscription/list" // 查询订阅商品列表
|
||||||
|
|
||||||
/// AI
|
/// AI
|
||||||
#define API_AI_TALK @"/chat/talk" // 排行榜标签列表
|
#define API_AI_TALK @"/chat/talk"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
04050ECB2F10FB8F008051EB /* UIImage+KBColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 047C655D2EBCD5B20035E841 /* UIImage+KBColor.m */; };
|
||||||
041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */ = {isa = PBXBuildFile; fileRef = 041007D12ECE012000D203BB /* KBSkinIconMap.strings */; };
|
041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */ = {isa = PBXBuildFile; fileRef = 041007D12ECE012000D203BB /* KBSkinIconMap.strings */; };
|
||||||
041007D42ECE012500D203BB /* 002.zip in Resources */ = {isa = PBXBuildFile; fileRef = 041007D32ECE012500D203BB /* 002.zip */; };
|
041007D42ECE012500D203BB /* 002.zip in Resources */ = {isa = PBXBuildFile; fileRef = 041007D32ECE012500D203BB /* 002.zip */; };
|
||||||
04122F5D2EC5E5A900EF7AB3 /* KBLoginVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 04122F5B2EC5E5A900EF7AB3 /* KBLoginVM.m */; };
|
04122F5D2EC5E5A900EF7AB3 /* KBLoginVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 04122F5B2EC5E5A900EF7AB3 /* KBLoginVM.m */; };
|
||||||
@@ -67,7 +68,6 @@
|
|||||||
04791F982ED49CE7004E8522 /* KBFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F972ED49CE7004E8522 /* KBFont.m */; };
|
04791F982ED49CE7004E8522 /* KBFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F972ED49CE7004E8522 /* KBFont.m */; };
|
||||||
04791F992ED49CE7004E8522 /* KBFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F972ED49CE7004E8522 /* KBFont.m */; };
|
04791F992ED49CE7004E8522 /* KBFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F972ED49CE7004E8522 /* KBFont.m */; };
|
||||||
04791FF72ED5B985004E8522 /* Christmas.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04791FF62ED5B985004E8522 /* Christmas.zip */; };
|
04791FF72ED5B985004E8522 /* Christmas.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04791FF62ED5B985004E8522 /* Christmas.zip */; };
|
||||||
04791FFB2ED5EAB8004E8522 /* normal_hei_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04791FFA2ED5EAB8004E8522 /* normal_hei_them.zip */; };
|
|
||||||
04791FFC2ED71D17004E8522 /* UIColor+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95E42EB220B5007BD342 /* UIColor+Extension.m */; };
|
04791FFC2ED71D17004E8522 /* UIColor+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95E42EB220B5007BD342 /* UIColor+Extension.m */; };
|
||||||
04791FFF2ED830FA004E8522 /* KBKeyboardMaskView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791FFE2ED830FA004E8522 /* KBKeyboardMaskView.m */; };
|
04791FFF2ED830FA004E8522 /* KBKeyboardMaskView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791FFE2ED830FA004E8522 /* KBKeyboardMaskView.m */; };
|
||||||
047920072ED86ABC004E8522 /* kb_guide_keyboard.gif in Resources */ = {isa = PBXBuildFile; fileRef = 047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */; };
|
047920072ED86ABC004E8522 /* kb_guide_keyboard.gif in Resources */ = {isa = PBXBuildFile; fileRef = 047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */; };
|
||||||
@@ -145,8 +145,6 @@
|
|||||||
049FB2292EC31BB000FAB05D /* KBChangeNicknamePopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2282EC31BB000FAB05D /* KBChangeNicknamePopView.m */; };
|
049FB2292EC31BB000FAB05D /* KBChangeNicknamePopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2282EC31BB000FAB05D /* KBChangeNicknamePopView.m */; };
|
||||||
049FB22C2EC31F8800FAB05D /* KBGenderPickerPopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB22B2EC31F8800FAB05D /* KBGenderPickerPopView.m */; };
|
049FB22C2EC31F8800FAB05D /* KBGenderPickerPopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB22B2EC31F8800FAB05D /* KBGenderPickerPopView.m */; };
|
||||||
049FB22F2EC34EB900FAB05D /* KBStreamTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */; };
|
049FB22F2EC34EB900FAB05D /* KBStreamTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */; };
|
||||||
049FB2322EC45A0000FAB05D /* KBStreamFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2312EC45A0000FAB05D /* KBStreamFetcher.m */; };
|
|
||||||
049FB2352EC45C6A00FAB05D /* NetworkStreamHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2342EC45C6A00FAB05D /* NetworkStreamHandler.m */; };
|
|
||||||
049FB23B2EC4766700FAB05D /* KBFunctionTagListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2372EC4766700FAB05D /* KBFunctionTagListView.m */; };
|
049FB23B2EC4766700FAB05D /* KBFunctionTagListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2372EC4766700FAB05D /* KBFunctionTagListView.m */; };
|
||||||
049FB23C2EC4766700FAB05D /* KBStreamOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2392EC4766700FAB05D /* KBStreamOverlayView.m */; };
|
049FB23C2EC4766700FAB05D /* KBStreamOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2392EC4766700FAB05D /* KBStreamOverlayView.m */; };
|
||||||
049FB23F2EC4B6EF00FAB05D /* KBULBridgeNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB23E2EC4B6EF00FAB05D /* KBULBridgeNotification.m */; };
|
049FB23F2EC4B6EF00FAB05D /* KBULBridgeNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB23E2EC4B6EF00FAB05D /* KBULBridgeNotification.m */; };
|
||||||
@@ -172,7 +170,8 @@
|
|||||||
04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 04C6EADC2EAF8CEB0089C901 /* KBToolBar.m */; };
|
04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 04C6EADC2EAF8CEB0089C901 /* KBToolBar.m */; };
|
||||||
04D1F6B22EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; };
|
04D1F6B22EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; };
|
||||||
04D1F6B32EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; };
|
04D1F6B32EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; };
|
||||||
04E1617C2F0FCA050022C23B /* normal_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04E1617B2F0FCA050022C23B /* normal_them.zip */; };
|
04E161832F10E6470022C23B /* normal_hei_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04E161812F10E6470022C23B /* normal_hei_them.zip */; };
|
||||||
|
04E161842F10E6470022C23B /* normal_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04E161822F10E6470022C23B /* normal_them.zip */; };
|
||||||
04FC95672EB0546C007BD342 /* KBKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95652EB0546C007BD342 /* KBKey.m */; };
|
04FC95672EB0546C007BD342 /* KBKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95652EB0546C007BD342 /* KBKey.m */; };
|
||||||
04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95692EB05497007BD342 /* KBKeyButton.m */; };
|
04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95692EB05497007BD342 /* KBKeyButton.m */; };
|
||||||
04FC956D2EB054B7007BD342 /* KBKeyboardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC956C2EB054B7007BD342 /* KBKeyboardView.m */; };
|
04FC956D2EB054B7007BD342 /* KBKeyboardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC956C2EB054B7007BD342 /* KBKeyboardView.m */; };
|
||||||
@@ -351,7 +350,6 @@
|
|||||||
04791F962ED49CE7004E8522 /* KBFont.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFont.h; sourceTree = "<group>"; };
|
04791F962ED49CE7004E8522 /* KBFont.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFont.h; sourceTree = "<group>"; };
|
||||||
04791F972ED49CE7004E8522 /* KBFont.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFont.m; sourceTree = "<group>"; };
|
04791F972ED49CE7004E8522 /* KBFont.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFont.m; sourceTree = "<group>"; };
|
||||||
04791FF62ED5B985004E8522 /* Christmas.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Christmas.zip; sourceTree = "<group>"; };
|
04791FF62ED5B985004E8522 /* Christmas.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Christmas.zip; sourceTree = "<group>"; };
|
||||||
04791FFA2ED5EAB8004E8522 /* normal_hei_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_hei_them.zip; sourceTree = "<group>"; };
|
|
||||||
04791FFD2ED830FA004E8522 /* KBKeyboardMaskView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyboardMaskView.h; sourceTree = "<group>"; };
|
04791FFD2ED830FA004E8522 /* KBKeyboardMaskView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyboardMaskView.h; sourceTree = "<group>"; };
|
||||||
04791FFE2ED830FA004E8522 /* KBKeyboardMaskView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardMaskView.m; sourceTree = "<group>"; };
|
04791FFE2ED830FA004E8522 /* KBKeyboardMaskView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardMaskView.m; sourceTree = "<group>"; };
|
||||||
047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = kb_guide_keyboard.gif; sourceTree = "<group>"; };
|
047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = kb_guide_keyboard.gif; sourceTree = "<group>"; };
|
||||||
@@ -495,10 +493,6 @@
|
|||||||
049FB22B2EC31F8800FAB05D /* KBGenderPickerPopView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBGenderPickerPopView.m; sourceTree = "<group>"; };
|
049FB22B2EC31F8800FAB05D /* KBGenderPickerPopView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBGenderPickerPopView.m; sourceTree = "<group>"; };
|
||||||
049FB22D2EC34EB900FAB05D /* KBStreamTextView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamTextView.h; sourceTree = "<group>"; };
|
049FB22D2EC34EB900FAB05D /* KBStreamTextView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamTextView.h; sourceTree = "<group>"; };
|
||||||
049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBStreamTextView.m; sourceTree = "<group>"; };
|
049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBStreamTextView.m; sourceTree = "<group>"; };
|
||||||
049FB2302EC45A0000FAB05D /* KBStreamFetcher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamFetcher.h; sourceTree = "<group>"; };
|
|
||||||
049FB2312EC45A0000FAB05D /* KBStreamFetcher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBStreamFetcher.m; sourceTree = "<group>"; };
|
|
||||||
049FB2332EC45C6A00FAB05D /* NetworkStreamHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NetworkStreamHandler.h; sourceTree = "<group>"; };
|
|
||||||
049FB2342EC45C6A00FAB05D /* NetworkStreamHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NetworkStreamHandler.m; sourceTree = "<group>"; };
|
|
||||||
049FB2362EC4766700FAB05D /* KBFunctionTagListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFunctionTagListView.h; sourceTree = "<group>"; };
|
049FB2362EC4766700FAB05D /* KBFunctionTagListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFunctionTagListView.h; sourceTree = "<group>"; };
|
||||||
049FB2372EC4766700FAB05D /* KBFunctionTagListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFunctionTagListView.m; sourceTree = "<group>"; };
|
049FB2372EC4766700FAB05D /* KBFunctionTagListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFunctionTagListView.m; sourceTree = "<group>"; };
|
||||||
049FB2382EC4766700FAB05D /* KBStreamOverlayView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamOverlayView.h; sourceTree = "<group>"; };
|
049FB2382EC4766700FAB05D /* KBStreamOverlayView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamOverlayView.h; sourceTree = "<group>"; };
|
||||||
@@ -540,7 +534,8 @@
|
|||||||
04C6EAE12EAF940F0089C901 /* KBPermissionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPermissionViewController.m; sourceTree = "<group>"; };
|
04C6EAE12EAF940F0089C901 /* KBPermissionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPermissionViewController.m; sourceTree = "<group>"; };
|
||||||
04D1F6B02EDFF10A00B12345 /* KBSkinInstallBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinInstallBridge.h; sourceTree = "<group>"; };
|
04D1F6B02EDFF10A00B12345 /* KBSkinInstallBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinInstallBridge.h; sourceTree = "<group>"; };
|
||||||
04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinInstallBridge.m; sourceTree = "<group>"; };
|
04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinInstallBridge.m; sourceTree = "<group>"; };
|
||||||
04E1617B2F0FCA050022C23B /* normal_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_them.zip; sourceTree = "<group>"; };
|
04E161812F10E6470022C23B /* normal_hei_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_hei_them.zip; sourceTree = "<group>"; };
|
||||||
|
04E161822F10E6470022C23B /* normal_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_them.zip; sourceTree = "<group>"; };
|
||||||
04FC953A2EAFAE56007BD342 /* KeyBoardPrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyBoardPrefixHeader.pch; sourceTree = "<group>"; };
|
04FC953A2EAFAE56007BD342 /* KeyBoardPrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyBoardPrefixHeader.pch; sourceTree = "<group>"; };
|
||||||
04FC95642EB0546C007BD342 /* KBKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKey.h; sourceTree = "<group>"; };
|
04FC95642EB0546C007BD342 /* KBKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKey.h; sourceTree = "<group>"; };
|
||||||
04FC95652EB0546C007BD342 /* KBKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKey.m; sourceTree = "<group>"; };
|
04FC95652EB0546C007BD342 /* KBKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKey.m; sourceTree = "<group>"; };
|
||||||
@@ -691,13 +686,13 @@
|
|||||||
041007D02ECE010100D203BB /* Resource */ = {
|
041007D02ECE010100D203BB /* Resource */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
04E1617B2F0FCA050022C23B /* normal_them.zip */,
|
04E161812F10E6470022C23B /* normal_hei_them.zip */,
|
||||||
|
04E161822F10E6470022C23B /* normal_them.zip */,
|
||||||
A1B2C3EC2F20000000000001 /* kb_words.txt */,
|
A1B2C3EC2F20000000000001 /* kb_words.txt */,
|
||||||
A1B2C3F02F20000000000002 /* kb_keyboard_layout_config.json */,
|
A1B2C3F02F20000000000002 /* kb_keyboard_layout_config.json */,
|
||||||
0498BDF42EEC50EE006CC1D5 /* emoji_categories.json */,
|
0498BDF42EEC50EE006CC1D5 /* emoji_categories.json */,
|
||||||
041007D12ECE012000D203BB /* KBSkinIconMap.strings */,
|
041007D12ECE012000D203BB /* KBSkinIconMap.strings */,
|
||||||
041007D32ECE012500D203BB /* 002.zip */,
|
041007D32ECE012500D203BB /* 002.zip */,
|
||||||
04791FFA2ED5EAB8004E8522 /* normal_hei_them.zip */,
|
|
||||||
04791FF62ED5B985004E8522 /* Christmas.zip */,
|
04791FF62ED5B985004E8522 /* Christmas.zip */,
|
||||||
);
|
);
|
||||||
path = Resource;
|
path = Resource;
|
||||||
@@ -1726,10 +1721,6 @@
|
|||||||
0498BDD92EE7ECEA006CC1D5 /* WJXEventSource */,
|
0498BDD92EE7ECEA006CC1D5 /* WJXEventSource */,
|
||||||
A1B2C3E02EB0C0A100000001 /* KBNetworkManager.h */,
|
A1B2C3E02EB0C0A100000001 /* KBNetworkManager.h */,
|
||||||
A1B2C3E12EB0C0A100000001 /* KBNetworkManager.m */,
|
A1B2C3E12EB0C0A100000001 /* KBNetworkManager.m */,
|
||||||
049FB2302EC45A0000FAB05D /* KBStreamFetcher.h */,
|
|
||||||
049FB2312EC45A0000FAB05D /* KBStreamFetcher.m */,
|
|
||||||
049FB2332EC45C6A00FAB05D /* NetworkStreamHandler.h */,
|
|
||||||
049FB2342EC45C6A00FAB05D /* NetworkStreamHandler.m */,
|
|
||||||
);
|
);
|
||||||
path = Network;
|
path = Network;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1824,13 +1815,13 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
04E161832F10E6470022C23B /* normal_hei_them.zip in Resources */,
|
||||||
|
04E161842F10E6470022C23B /* normal_them.zip in Resources */,
|
||||||
04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */,
|
04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */,
|
||||||
041007D42ECE012500D203BB /* 002.zip in Resources */,
|
041007D42ECE012500D203BB /* 002.zip in Resources */,
|
||||||
04E1617C2F0FCA050022C23B /* normal_them.zip in Resources */,
|
|
||||||
041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */,
|
041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */,
|
||||||
A1B2C3ED2F20000000000001 /* kb_words.txt in Resources */,
|
A1B2C3ED2F20000000000001 /* kb_words.txt in Resources */,
|
||||||
A1B2C3F12F20000000000002 /* kb_keyboard_layout_config.json in Resources */,
|
A1B2C3F12F20000000000002 /* kb_keyboard_layout_config.json in Resources */,
|
||||||
04791FFB2ED5EAB8004E8522 /* normal_hei_them.zip in Resources */,
|
|
||||||
0498BDF52EEC50EE006CC1D5 /* emoji_categories.json in Resources */,
|
0498BDF52EEC50EE006CC1D5 /* emoji_categories.json in Resources */,
|
||||||
04791FF72ED5B985004E8522 /* Christmas.zip in Resources */,
|
04791FF72ED5B985004E8522 /* Christmas.zip in Resources */,
|
||||||
04286A0B2ECD88B400CE730C /* KeyboardAssets.xcassets in Resources */,
|
04286A0B2ECD88B400CE730C /* KeyboardAssets.xcassets in Resources */,
|
||||||
@@ -1930,13 +1921,13 @@
|
|||||||
files = (
|
files = (
|
||||||
0498BD862EE1BEC9006CC1D5 /* KBSignUtils.m in Sources */,
|
0498BD862EE1BEC9006CC1D5 /* KBSignUtils.m in Sources */,
|
||||||
04791FFC2ED71D17004E8522 /* UIColor+Extension.m in Sources */,
|
04791FFC2ED71D17004E8522 /* UIColor+Extension.m in Sources */,
|
||||||
049FB2322EC45A0000FAB05D /* KBStreamFetcher.m in Sources */,
|
|
||||||
0450AC4A2EF2C3ED00B6AF06 /* KBKeyboardSubscriptionOptionCell.m in Sources */,
|
0450AC4A2EF2C3ED00B6AF06 /* KBKeyboardSubscriptionOptionCell.m in Sources */,
|
||||||
04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */,
|
04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */,
|
||||||
04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */,
|
04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */,
|
||||||
A1B2C3EB2F20000000000001 /* KBSuggestionBarView.m in Sources */,
|
A1B2C3EB2F20000000000001 /* KBSuggestionBarView.m in Sources */,
|
||||||
04FC95792EB09BC8007BD342 /* KBKeyBoardMainView.m in Sources */,
|
04FC95792EB09BC8007BD342 /* KBKeyBoardMainView.m in Sources */,
|
||||||
04FEDAB32EEDB05000123456 /* KBEmojiPanelView.m in Sources */,
|
04FEDAB32EEDB05000123456 /* KBEmojiPanelView.m in Sources */,
|
||||||
|
04050ECB2F10FB8F008051EB /* UIImage+KBColor.m in Sources */,
|
||||||
04FEDB032EFE000000123456 /* KBEmojiBottomBarView.m in Sources */,
|
04FEDB032EFE000000123456 /* KBEmojiBottomBarView.m in Sources */,
|
||||||
0498BD8C2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */,
|
0498BD8C2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */,
|
||||||
046131142ECF454500A6FADF /* KBKeyPreviewView.m in Sources */,
|
046131142ECF454500A6FADF /* KBKeyPreviewView.m in Sources */,
|
||||||
@@ -1949,7 +1940,6 @@
|
|||||||
04A9FE1A2EB892460020DB6D /* KBLocalizationManager.m in Sources */,
|
04A9FE1A2EB892460020DB6D /* KBLocalizationManager.m in Sources */,
|
||||||
A1B2C3EA2F20000000000001 /* KBSuggestionEngine.m in Sources */,
|
A1B2C3EA2F20000000000001 /* KBSuggestionEngine.m in Sources */,
|
||||||
A1B2C3E22EB0C0A100000001 /* KBNetworkManager.m in Sources */,
|
A1B2C3E22EB0C0A100000001 /* KBNetworkManager.m in Sources */,
|
||||||
049FB2352EC45C6A00FAB05D /* NetworkStreamHandler.m in Sources */,
|
|
||||||
04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */,
|
04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */,
|
||||||
04FEDAA12EEDB00100123456 /* KBEmojiDataProvider.m in Sources */,
|
04FEDAA12EEDB00100123456 /* KBEmojiDataProvider.m in Sources */,
|
||||||
04FC95B22EB0B2CC007BD342 /* KBSettingView.m in Sources */,
|
04FC95B22EB0B2CC007BD342 /* KBSettingView.m in Sources */,
|
||||||
|
|||||||
Reference in New Issue
Block a user