This commit is contained in:
2025-12-17 18:22:37 +08:00
parent 1e04e7c39a
commit 4a26419e67
4 changed files with 190 additions and 71 deletions

View File

@@ -0,0 +1,21 @@
//
// KBKeyboardSubscriptionFeatureItemView.h
// CustomKeyboard
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/// 顶部滚动的功能点 Item左图右文
@interface KBKeyboardSubscriptionFeatureItemView : UIView
- (void)configureWithImage:(UIImage *)image title:(NSString *)title;
/// 根据 title 计算推荐宽度textWidth + 50图片 35 + 间距 5 + 左右内边距各 5
+ (CGFloat)preferredWidthForTitle:(NSString *)title;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,86 @@
//
// KBKeyboardSubscriptionFeatureItemView.m
// CustomKeyboard
//
#import "KBKeyboardSubscriptionFeatureItemView.h"
#import "Masonry.h"
@interface KBKeyboardSubscriptionFeatureItemView ()
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *titleLabel;
@end
@implementation KBKeyboardSubscriptionFeatureItemView
static const CGFloat kKBFeatureItemPadding = 5.0;
static const CGFloat kKBFeatureItemIconSize = 35.0;
static const CGFloat kKBFeatureItemGap = 5.0;
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// self.layer.cornerRadius = 24;
// self.layer.masksToBounds = YES;
// self.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.85];
[self addSubview:self.iconView];
[self addSubview:self.titleLabel];
[self.iconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.mas_left).offset(kKBFeatureItemPadding);
make.centerY.equalTo(self.mas_centerY);
make.width.height.mas_equalTo(kKBFeatureItemIconSize);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.iconView.mas_right).offset(kKBFeatureItemGap);
make.centerY.equalTo(self.mas_centerY);
make.right.equalTo(self.mas_right).offset(-kKBFeatureItemPadding);
}];
}
return self;
}
- (void)configureWithImage:(UIImage *)image title:(NSString *)title {
self.iconView.image = image;
self.titleLabel.text = title ?: @"";
}
+ (CGFloat)preferredWidthForTitle:(NSString *)title {
UIFont *font = [UIFont systemFontOfSize:13 weight:UIFontWeightSemibold];
NSString *text = title ?: @"";
NSArray<NSString *> *lines = [text componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
CGFloat maxLineWidth = 0;
for (NSString *line in lines) {
NSString *trimLine = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if (trimLine.length == 0) { continue; }
CGSize size = [trimLine sizeWithAttributes:@{NSFontAttributeName: font}];
maxLineWidth = MAX(maxLineWidth, ceil(size.width));
}
if (maxLineWidth <= 0) { maxLineWidth = 80; }
CGFloat width = maxLineWidth + 50.0; // 5 + 35 + 5 + 5
width = MIN(MAX(width, 120.0), 240.0);
return width;
}
- (UIImageView *)iconView {
if (!_iconView) {
_iconView = [[UIImageView alloc] init];
_iconView.contentMode = UIViewContentModeScaleAspectFit;
}
return _iconView;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [UIFont systemFontOfSize:13 weight:UIFontWeightSemibold];
_titleLabel.textColor = [UIColor colorWithHex:0x4A4A4A];
_titleLabel.numberOfLines = 0;
_titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
return _titleLabel;
}
@end

View File

@@ -7,6 +7,7 @@
#import "KBKeyboardSubscriptionProduct.h" #import "KBKeyboardSubscriptionProduct.h"
#import "KBNetworkManager.h" #import "KBNetworkManager.h"
#import "KBFullAccessManager.h" #import "KBFullAccessManager.h"
#import "KBKeyboardSubscriptionFeatureItemView.h"
#import <MJExtension/MJExtension.h> #import <MJExtension/MJExtension.h>
static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptionCellId"; static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptionCellId";
@@ -19,7 +20,6 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
@interface KBKeyboardSubscriptionView () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> @interface KBKeyboardSubscriptionView () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, strong) UIImageView *cardView; @property (nonatomic, strong) UIImageView *cardView;
@property (nonatomic, strong) UIButton *closeButton; @property (nonatomic, strong) UIButton *closeButton;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIScrollView *featureScrollView; @property (nonatomic, strong) UIScrollView *featureScrollView;
@property (nonatomic, strong) UIView *featureContentView; @property (nonatomic, strong) UIView *featureContentView;
@property (nonatomic, strong) UICollectionView *collectionView; @property (nonatomic, strong) UICollectionView *collectionView;
@@ -55,7 +55,6 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
- (void)layoutSubviews { - (void)layoutSubviews {
[super layoutSubviews]; [super layoutSubviews];
self.featureLoopWidth = self.featureScrollView.contentSize.width * 0.5f;
[self startFeatureTickerIfNeeded]; [self startFeatureTickerIfNeeded];
} }
@@ -103,7 +102,6 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
}]; }];
[self.cardView addSubview:self.closeButton]; [self.cardView addSubview:self.closeButton];
[self.cardView addSubview:self.titleLabel];
[self.cardView addSubview:self.featureScrollView]; [self.cardView addSubview:self.featureScrollView];
[self.cardView addSubview:self.collectionView]; [self.cardView addSubview:self.collectionView];
[self.cardView addSubview:self.purchaseButton]; [self.cardView addSubview:self.purchaseButton];
@@ -114,25 +112,20 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) { [self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.cardView.mas_left).offset(12); make.left.equalTo(self.cardView.mas_left).offset(12);
make.top.equalTo(self.cardView.mas_top).offset(10); make.top.equalTo(self.cardView.mas_top).offset(25);
make.width.height.mas_equalTo(28); make.width.height.mas_equalTo(28);
}]; }];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.closeButton.mas_centerY);
make.centerX.equalTo(self.cardView.mas_centerX);
}];
[self.featureScrollView mas_makeConstraints:^(MASConstraintMaker *make) { [self.featureScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.closeButton.mas_bottom).offset(8); make.left.equalTo(self.closeButton.mas_right).offset(5);
make.left.equalTo(self.cardView.mas_left).offset(12); make.centerY.equalTo(self.closeButton);
make.right.equalTo(self.cardView.mas_right).offset(-12); make.right.equalTo(self.cardView.mas_right).offset(-12);
make.height.mas_equalTo(54); make.height.mas_equalTo(48);
}]; }];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.featureScrollView); make.left.right.equalTo(self.featureScrollView);
make.top.equalTo(self.featureScrollView.mas_bottom).offset(12); make.top.equalTo(self.featureScrollView.mas_bottom).offset(10);
make.height.mas_equalTo(138); make.height.mas_equalTo(138);
}]; }];
@@ -173,28 +166,66 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
} }
- (void)setupFeatureItems { - (void)setupFeatureItems {
self.featureItems = @[ NSArray *titles = @[
@{@"emoji": @"🤖", @"title": KBLocalized(@"Wireless Sub-ai Dialogue")}, KBLocalized(@"Wireless Sub-ai\nDialogue"),
@{@"emoji": @"⌨️", @"title": KBLocalized(@"Personalized Keyboard")}, KBLocalized(@"Personalized\nKeyboard"),
@{@"emoji": @"🧠", @"title": KBLocalized(@"Creative Prompt Library")}, KBLocalized(@"Chat\nPersona"),
@{@"emoji": @"💬", @"title": KBLocalized(@"Chat Personalized Coach")} KBLocalized(@"Emotional\nCounseling")
]; ];
NSArray *images = @[
[UIImage imageNamed:@"home_ai_icon"] ?: [UIImage new],
[UIImage imageNamed:@"home_keyboard_icon"] ?: [UIImage new],
[UIImage imageNamed:@"home_chat_icon"] ?: [UIImage new],
[UIImage imageNamed:@"home_emotion_icon"] ?: [UIImage new]
];
NSMutableArray *items = [NSMutableArray array];
[titles enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
UIImage *img = (idx < images.count) ? images[idx] : nil;
if (!obj) { obj = @""; }
if (!img) { img = [UIImage new]; }
[items addObject:@{@"title": obj, @"image": img}];
}];
self.featureItems = [items copy];
[self rebuildFeatureBadges]; [self rebuildFeatureBadges];
} }
- (void)rebuildFeatureBadges { - (void)rebuildFeatureBadges {
[self.featureContentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; [self.featureContentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
NSArray *loopData = [self.featureItems arrayByAddingObjectsFromArray:self.featureItems]; if (self.featureItems.count == 0) {
UIView *previous = nil; self.featureScrollView.contentSize = CGSizeZero;
self.featureLoopWidth = 0;
[self stopFeatureTicker];
return;
}
BOOL shouldLoop = (self.featureItems.count > 1);
CGFloat spacing = 12.0; CGFloat spacing = 12.0;
for (NSDictionary *info in loopData) { NSInteger baseCount = self.featureItems.count;
UIView *badge = [self buildBadgeWithEmoji:info[@"emoji"] title:info[@"title"]];
NSMutableArray<NSNumber *> *baseWidths = [NSMutableArray arrayWithCapacity:baseCount];
CGFloat baseTotalWidth = 0.0;
for (NSInteger i = 0; i < baseCount; i++) {
NSDictionary *info = self.featureItems[i];
NSString *title = [info[@"title"] isKindOfClass:NSString.class] ? info[@"title"] : @"";
CGFloat width = [KBKeyboardSubscriptionFeatureItemView preferredWidthForTitle:title];
[baseWidths addObject:@(width)];
baseTotalWidth += width;
if (i > 0) { baseTotalWidth += spacing; }
}
NSArray *loopData = shouldLoop ? [self.featureItems arrayByAddingObjectsFromArray:self.featureItems] : self.featureItems;
CGFloat totalWidth = shouldLoop ? (baseTotalWidth * 2 + spacing) : baseTotalWidth;
UIView *previous = nil;
for (NSInteger idx = 0; idx < loopData.count; idx++) {
NSDictionary *info = loopData[idx];
UIImage *img = [info[@"image"] isKindOfClass:UIImage.class] ? info[@"image"] : nil;
NSString *title = [info[@"title"] isKindOfClass:NSString.class] ? info[@"title"] : @"";
CGFloat width = (baseCount > 0) ? baseWidths[(NSUInteger)(idx % baseCount)].doubleValue : 120.0;
KBKeyboardSubscriptionFeatureItemView *badge = [[KBKeyboardSubscriptionFeatureItemView alloc] init];
[badge configureWithImage:(img ?: [UIImage new]) title:title];
[self.featureContentView addSubview:badge]; [self.featureContentView addSubview:badge];
CGFloat textWidth = [info[@"title"] boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, 24)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:13 weight:UIFontWeightSemibold]}
context:nil].size.width;
CGFloat width = MIN(MAX(textWidth + 60, 150), 240);
[badge mas_makeConstraints:^(MASConstraintMaker *make) { [badge mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.equalTo(self.featureContentView); make.top.bottom.equalTo(self.featureContentView);
make.width.mas_equalTo(width); make.width.mas_equalTo(width);
@@ -206,6 +237,7 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
}]; }];
previous = badge; previous = badge;
} }
__weak typeof(self) weakSelf = self; __weak typeof(self) weakSelf = self;
[self.featureContentView mas_remakeConstraints:^(MASConstraintMaker *make) { [self.featureContentView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.equalTo(weakSelf.featureScrollView); make.top.bottom.equalTo(weakSelf.featureScrollView);
@@ -217,37 +249,21 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
make.right.equalTo(weakSelf.featureScrollView); make.right.equalTo(weakSelf.featureScrollView);
} }
}]; }];
} CGFloat minWidth = CGRectGetWidth(self.featureScrollView.bounds);
if (minWidth <= 0) { minWidth = [UIScreen mainScreen].bounds.size.width - 24; }
- (UIView *)buildBadgeWithEmoji:(NSString *)emoji title:(NSString *)title { CGFloat height = CGRectGetHeight(self.featureScrollView.bounds);
UIView *container = [[UIView alloc] init]; if (height <= 0) { height = 48; }
container.layer.cornerRadius = 24; CGFloat contentWidth = totalWidth;
container.layer.masksToBounds = YES; if (contentWidth <= minWidth) {
container.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.85]; contentWidth = minWidth;
self.featureLoopWidth = 0;
UILabel *emojiLabel = [[UILabel alloc] init]; [self stopFeatureTicker];
emojiLabel.text = emoji ?: @"✨"; self.featureScrollView.contentOffset = CGPointZero;
emojiLabel.font = [UIFont systemFontOfSize:20]; } else {
self.featureLoopWidth = shouldLoop ? (baseTotalWidth + spacing) : 0.0;
UILabel *textLabel = [[UILabel alloc] init]; [self startFeatureTickerIfNeeded];
textLabel.text = title ?: @""; }
textLabel.font = [UIFont systemFontOfSize:13 weight:UIFontWeightSemibold]; self.featureScrollView.contentSize = CGSizeMake(contentWidth, height);
textLabel.textColor = [UIColor colorWithHex:0x4A4A4A];
[container addSubview:emojiLabel];
[container addSubview:textLabel];
[emojiLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(container.mas_left).offset(14);
make.centerY.equalTo(container.mas_centerY);
}];
[textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(emojiLabel.mas_right).offset(10);
make.centerY.equalTo(container.mas_centerY);
make.right.equalTo(container.mas_right).offset(-14);
}];
return container;
} }
#pragma mark - Actions #pragma mark - Actions
@@ -423,10 +439,10 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
- (UIImageView *)cardView { - (UIImageView *)cardView {
if (!_cardView) { if (!_cardView) {
_cardView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"keybord_bg_icon"]]; _cardView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"keybord_bg_icon"]];
// _cardView.layer.cornerRadius = 20; _cardView.layer.cornerRadius = 20;
// _cardView.layer.masksToBounds = YES; _cardView.layer.masksToBounds = YES;
_cardView.userInteractionEnabled = YES;
_cardView.contentMode = UIViewContentModeScaleAspectFill; _cardView.contentMode = UIViewContentModeScaleAspectFill;
_cardView.clipsToBounds = true;
} }
return _cardView; return _cardView;
} }
@@ -445,16 +461,6 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
return _closeButton; return _closeButton;
} }
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.text = KBLocalized(@"Premium Subscription");
_titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
_titleLabel.textColor = [UIColor colorWithHex:0x24556B];
}
return _titleLabel;
}
- (UIScrollView *)featureScrollView { - (UIScrollView *)featureScrollView {
if (!_featureScrollView) { if (!_featureScrollView) {
_featureScrollView = [[UIScrollView alloc] init]; _featureScrollView = [[UIScrollView alloc] init];

View File

@@ -216,6 +216,7 @@
ECC9EE02174D86E8D792472F /* Pods_keyBoard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 967065BB5230E43F293B3AF9 /* Pods_keyBoard.framework */; }; ECC9EE02174D86E8D792472F /* Pods_keyBoard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 967065BB5230E43F293B3AF9 /* Pods_keyBoard.framework */; };
04FEDC122F00010000999999 /* KBKeyboardSubscriptionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDC112F00010000999999 /* KBKeyboardSubscriptionView.m */; }; 04FEDC122F00010000999999 /* KBKeyboardSubscriptionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDC112F00010000999999 /* KBKeyboardSubscriptionView.m */; };
04FEDC222F00020000999999 /* KBKeyboardSubscriptionProduct.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDC212F00020000999999 /* KBKeyboardSubscriptionProduct.m */; }; 04FEDC222F00020000999999 /* KBKeyboardSubscriptionProduct.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDC212F00020000999999 /* KBKeyboardSubscriptionProduct.m */; };
04FEDC322F00030000999999 /* KBKeyboardSubscriptionFeatureItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDC312F00030000999999 /* KBKeyboardSubscriptionFeatureItemView.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@@ -539,6 +540,8 @@
04FC95B12EB0B2CC007BD342 /* KBSettingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSettingView.m; sourceTree = "<group>"; }; 04FC95B12EB0B2CC007BD342 /* KBSettingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSettingView.m; sourceTree = "<group>"; };
04FEDC102F00010000999999 /* KBKeyboardSubscriptionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyboardSubscriptionView.h; sourceTree = "<group>"; }; 04FEDC102F00010000999999 /* KBKeyboardSubscriptionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyboardSubscriptionView.h; sourceTree = "<group>"; };
04FEDC112F00010000999999 /* KBKeyboardSubscriptionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardSubscriptionView.m; sourceTree = "<group>"; }; 04FEDC112F00010000999999 /* KBKeyboardSubscriptionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardSubscriptionView.m; sourceTree = "<group>"; };
04FEDC302F00030000999999 /* KBKeyboardSubscriptionFeatureItemView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyboardSubscriptionFeatureItemView.h; sourceTree = "<group>"; };
04FEDC312F00030000999999 /* KBKeyboardSubscriptionFeatureItemView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardSubscriptionFeatureItemView.m; sourceTree = "<group>"; };
04FC95C72EB1E4C9007BD342 /* BaseNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseNavigationController.h; sourceTree = "<group>"; }; 04FC95C72EB1E4C9007BD342 /* BaseNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseNavigationController.h; sourceTree = "<group>"; };
04FC95C82EB1E4C9007BD342 /* BaseNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseNavigationController.m; sourceTree = "<group>"; }; 04FC95C82EB1E4C9007BD342 /* BaseNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseNavigationController.m; sourceTree = "<group>"; };
04FC95CA2EB1E780007BD342 /* BaseTabBarController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseTabBarController.h; sourceTree = "<group>"; }; 04FC95CA2EB1E780007BD342 /* BaseTabBarController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseTabBarController.h; sourceTree = "<group>"; };
@@ -1139,6 +1142,8 @@
04FC95B12EB0B2CC007BD342 /* KBSettingView.m */, 04FC95B12EB0B2CC007BD342 /* KBSettingView.m */,
04FEDC102F00010000999999 /* KBKeyboardSubscriptionView.h */, 04FEDC102F00010000999999 /* KBKeyboardSubscriptionView.h */,
04FEDC112F00010000999999 /* KBKeyboardSubscriptionView.m */, 04FEDC112F00010000999999 /* KBKeyboardSubscriptionView.m */,
04FEDC302F00030000999999 /* KBKeyboardSubscriptionFeatureItemView.h */,
04FEDC312F00030000999999 /* KBKeyboardSubscriptionFeatureItemView.m */,
049FB22D2EC34EB900FAB05D /* KBStreamTextView.h */, 049FB22D2EC34EB900FAB05D /* KBStreamTextView.h */,
049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */, 049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */,
049FB23A2EC4766700FAB05D /* Function */, 049FB23A2EC4766700FAB05D /* Function */,
@@ -1843,6 +1848,7 @@
04FEDAA12EEDB00100123456 /* KBEmojiDataProvider.m in Sources */, 04FEDAA12EEDB00100123456 /* KBEmojiDataProvider.m in Sources */,
04FC95B22EB0B2CC007BD342 /* KBSettingView.m in Sources */, 04FC95B22EB0B2CC007BD342 /* KBSettingView.m in Sources */,
04FEDC122F00010000999999 /* KBKeyboardSubscriptionView.m in Sources */, 04FEDC122F00010000999999 /* KBKeyboardSubscriptionView.m in Sources */,
04FEDC322F00030000999999 /* KBKeyboardSubscriptionFeatureItemView.m in Sources */,
04791F8E2ED469C0004E8522 /* KBHostAppLauncher.m in Sources */, 04791F8E2ED469C0004E8522 /* KBHostAppLauncher.m in Sources */,
049FB23B2EC4766700FAB05D /* KBFunctionTagListView.m in Sources */, 049FB23B2EC4766700FAB05D /* KBFunctionTagListView.m in Sources */,
049FB23C2EC4766700FAB05D /* KBStreamOverlayView.m in Sources */, 049FB23C2EC4766700FAB05D /* KBStreamOverlayView.m in Sources */,