This commit is contained in:
2025-11-14 16:34:01 +08:00
parent eacac8425c
commit 66a1ddef66
16 changed files with 262 additions and 55 deletions

View File

@@ -9,7 +9,7 @@
NS_ASSUME_NONNULL_BEGIN
@interface KBGuideVC : UIViewController
@interface KBGuideVC : BaseViewController
@end

View File

@@ -29,6 +29,8 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *items; // [{type, text}]
///
@property (nonatomic, strong, nullable) KBPermissionViewController *permVC;
///
@property (nonatomic, copy, nullable) NSString *kb_lastInputModeIdentifier;
@end
@@ -45,8 +47,9 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
[self.inputBar addSubview:self.textField];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.equalTo(self.view);
make.left.right.equalTo(self.view);
make.bottom.equalTo(self.view);
make.top.mas_equalTo(KB_NAV_TOTAL_HEIGHT);
}];
[self.inputBar mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -83,8 +86,17 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
// /
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kb_checkKeyboardPermission) name:UIApplicationDidBecomeActiveNotification object:nil];
// 使
NSArray<NSString *> *modeNotiNames = @[ @"UITextInputCurrentInputModeDidChangeNotification",
@"UITextInputCurrentInputModeDidChange" ];
for (NSString *n in modeNotiNames) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kb_inputModeDidChange:) name:n object:nil];
}
//
[self kb_preparePermissionOverlayIfNeeded];
}
- (void)dealloc {
@@ -95,6 +107,19 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
[super viewWillAppear:animated];
//
[self kb_checkKeyboardPermission];
// /
BOOL permissionReady = (self.permVC && self.permVC.view.hidden == YES);
if (permissionReady) {
// textInputMode
if (![self.textField isFirstResponder]) {
[self.textField becomeFirstResponder];
}
// 线
// UIKeyboardWillChangeFrame
dispatch_async(dispatch_get_main_queue(), ^{
[self kb_evaluateCurrentInputModeAndNotifyIfNeeded];
});
}
}
///
@@ -179,6 +204,8 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
// self.tableView.scrollIndicatorInsets = inset;
} completion:^(BOOL finished) {
[self scrollToBottomAnimated:YES];
//
[self kb_evaluateCurrentInputModeAndNotifyIfNeeded];
}];
}
@@ -191,6 +218,58 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
}
}
#pragma mark - Keyboard Detection
///
///
/// - `UITextField.textInputMode`
/// - KVC `identifier` bundle id
/// - `textField`
- (BOOL)kb_isMyExtensionKeyboardSelected {
UITextInputMode *mode = self.textField.textInputMode;
if (!mode) { return NO; }
NSString *identifier = nil;
@try {
// App
identifier = [mode valueForKey:@"identifier"];
} @catch (__unused NSException *e) {
identifier = nil;
}
if (![identifier isKindOfClass:[NSString class]]) { return NO; }
return [identifier rangeOfString:KB_KEYBOARD_EXTENSION_BUNDLE_ID].location != NSNotFound;
}
- (void)kb_inputModeDidChange:(NSNotification *)note {
//
[self kb_evaluateCurrentInputModeAndNotifyIfNeeded];
}
/// identifier nil
- (NSString *)kb_currentInputModeIdentifier {
UITextInputMode *mode = self.textField.textInputMode;
if (!mode) return nil;
NSString *identifier = nil;
@try { identifier = [mode valueForKey:@"identifier"]; } @catch (__unused NSException *e) { identifier = nil; }
return [identifier isKindOfClass:NSString.class] ? identifier : nil;
}
///
- (void)kb_evaluateCurrentInputModeAndNotifyIfNeeded {
//
if (![self.textField isFirstResponder]) return;
//
if (self.permVC && self.permVC.view.hidden == NO) return;
NSString *currId = [self kb_currentInputModeIdentifier];
if (currId.length == 0) return;
if ([self.kb_lastInputModeIdentifier isEqualToString:currId]) return; //
self.kb_lastInputModeIdentifier = currId;
BOOL isMine = [currId rangeOfString:KB_KEYBOARD_EXTENSION_BUNDLE_ID].location != NSNotFound;
[KBHUD showInfo:(isMine ? @"是自己的键盘" : @"❎不是自己的键盘")];
}
#pragma mark - UITableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

View File

@@ -163,8 +163,8 @@
#pragma mark - Actions
- (void)onTapBuyAction {
// if (self.onTapBuy) { self.onTapBuy(); }
// KBJfPay *vc = [[KBJfPay alloc] init];
// [KB_CURRENT_NAV pushViewController:vc animated:true];
KBJfPay *vc = [[KBJfPay alloc] init];
[KB_CURRENT_NAV pushViewController:vc animated:true];
}
#pragma mark - Lazy

View File

@@ -4,7 +4,7 @@
#import "KBJfPay.h"
#import "KBJfPayCell.h"
#import "FGIAPProductsFilter.h"
static NSString * const kKBJfPayCellId = @"kKBJfPayCellId";
@interface KBJfPay () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@@ -34,12 +34,15 @@ static NSString * const kKBJfPayCellId = @"kKBJfPayCellId";
@property (nonatomic, strong) NSArray<NSDictionary *> *data; // @{coins, price}
@property (nonatomic, assign) NSInteger selectedIndex; //
@property (nonatomic, strong) FGIAPProductsFilter *filter;
@end
@implementation KBJfPay
- (void)viewDidLoad {
[super viewDidLoad];
self.filter = [[FGIAPProductsFilter alloc] init];
self.bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"my_bg_icon"]];
self.bgImageView.contentMode = UIViewContentModeScaleAspectFill;
self.kb_navView.backgroundColor = [UIColor clearColor];
@@ -51,12 +54,12 @@ static NSString * const kKBJfPayCellId = @"kKBJfPayCellId";
//
self.data = @[
@{ @"coins": @690, @"price": @"$6.90" },
@{ @"coins": @1280, @"price": @"$12.90" },
@{ @"coins": @3290, @"price": @"$32.90" },
@{ @"coins": @4990, @"price": @"$49.90" },
@{ @"coins": @9990, @"price": @"$99.90" },
@{ @"coins": @19990,@"price": @"$199.90" },
@{ @"coins": @690, @"price": @"$6.90",@"product_id" : @"100_coin" },
@{ @"coins": @1280, @"price": @"$12.90" ,@"product_id" : @"vip_a_week" },
@{ @"coins": @3290, @"price": @"$32.90" ,@"product_id" : @"100_coin" },
@{ @"coins": @4990, @"price": @"$49.90" ,@"product_id" : @"100_coin" },
@{ @"coins": @9990, @"price": @"$99.90" ,@"product_id" : @"100_coin" },
@{ @"coins": @19990,@"price": @"$199.90" ,@"product_id" : @"100_coin" },
];
self.selectedIndex = 1; //
@@ -234,11 +237,20 @@ static NSString * const kKBJfPayCellId = @"kKBJfPayCellId";
#pragma mark - Actions
- (void)onTapPayButton {
// UI
if (self.selectedIndex >= 0 && self.selectedIndex < self.data.count) {
NSDictionary *item = self.data[self.selectedIndex];
NSString *msg = [NSString stringWithFormat:@"购买:%@ Coins %@", item[@"coins"], item[@"price"]];
[KBHUD showInfo:msg];
}
// if (self.selectedIndex >= 0 && self.selectedIndex < self.data.count) {
// NSDictionary *item = self.data[self.selectedIndex];
// NSString *msg = [NSString stringWithFormat:@"购买:%@ Coins %@", item[@"coins"], item[@"price"]];
// [KBHUD showInfo:msg];
// }
NSString *productId = @"com.yolo.vip.1month";
/// 2.
[self.filter requestProductsWith:[NSSet setWithObject:productId] completion:^(NSArray<SKProduct *> * _Nonnull products) {
NSLog(@"=====");
/// 3.
// [[FGIAPManager shared].iap buyProduct:products.firstObject onCompletion:^(NSString * _Nonnull message, FGIAPManagerPurchaseRusult result) {
// [self.view makeToast:message];
// }];
}];
}
- (void)agreementButtonAction{