This commit is contained in:
2025-12-16 20:05:33 +08:00
parent 9f7d805a52
commit 59297eac77
7 changed files with 128 additions and 66 deletions

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ai_key_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ai_key_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,13 @@
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface KBEmojiBottomBarView : UIView
@property (nonatomic, strong, readonly) UIScrollView *tabScrollView;
@property (nonatomic, strong, readonly) UIStackView *tabStackView;
@property (nonatomic, strong, readonly) UIButton *deleteButton;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,63 @@
#import "KBEmojiBottomBarView.h"
#import "Masonry.h"
@interface KBEmojiBottomBarView ()
@property (nonatomic, strong, readwrite) UIScrollView *tabScrollView;
@property (nonatomic, strong, readwrite) UIStackView *tabStackView;
@property (nonatomic, strong, readwrite) UIButton *deleteButton;
@end
@implementation KBEmojiBottomBarView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setupUI];
}
return self;
}
- (void)setupUI {
self.backgroundColor = [UIColor clearColor];
self.tabScrollView = [[UIScrollView alloc] init];
self.tabScrollView.showsHorizontalScrollIndicator = NO;
self.tabScrollView.backgroundColor = [UIColor clearColor];
[self addSubview:self.tabScrollView];
self.tabStackView = [[UIStackView alloc] init];
self.tabStackView.axis = UILayoutConstraintAxisHorizontal;
self.tabStackView.spacing = 8;
self.tabStackView.alignment = UIStackViewAlignmentFill;
[self.tabScrollView addSubview:self.tabStackView];
self.deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.deleteButton.layer.cornerRadius = 16;
self.deleteButton.layer.masksToBounds = YES;
// self.deleteButton.titleLabel.font = [UIFont systemFontOfSize:24 weight:UIFontWeightSemibold];
// [self.deleteButton setTitle:@"⌫" forState:UIControlStateNormal];
[self.deleteButton setImage:[UIImage imageNamed:@"kb_del_icon"] forState:UIControlStateNormal];
[self addSubview:self.deleteButton];
[self.tabScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.mas_left).offset(12);
make.right.equalTo(self.deleteButton.mas_left).offset(-12);
make.top.equalTo(self.mas_top).offset(4);
make.bottom.equalTo(self.mas_bottom).offset(-4);
}];
[self.tabStackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.tabScrollView);
make.height.equalTo(self.tabScrollView);
}];
[self.deleteButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.mas_right).offset(-12);
make.centerY.equalTo(self);
make.width.mas_equalTo(44);
make.height.equalTo(self.tabScrollView);
}];
}
@end

View File

@@ -9,6 +9,7 @@
#import "KBLocalizationManager.h" #import "KBLocalizationManager.h"
#import "Masonry.h" #import "Masonry.h"
#import "KBEmojiCollectionCell.h" #import "KBEmojiCollectionCell.h"
#import "KBEmojiBottomBarView.h"
@interface KBEmojiPanelView () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> @interface KBEmojiPanelView () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@@ -16,10 +17,7 @@
@property (nonatomic, strong) UILabel *titleLabel; @property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *backButton; @property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UICollectionView *collectionView; @property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) UIView *bottomBar; @property (nonatomic, strong) KBEmojiBottomBarView *bottomBar;
@property (nonatomic, strong) UIScrollView *tabScrollView;
@property (nonatomic, strong) UIStackView *tabStackView;
@property (nonatomic, strong) UIButton *deleteButton;
//@property (nonatomic, strong) UIButton *searchButton; //@property (nonatomic, strong) UIButton *searchButton;
@property (nonatomic, strong) NSArray<UIButton *> *tabButtons; @property (nonatomic, strong) NSArray<UIButton *> *tabButtons;
@property (nonatomic, strong) KBEmojiDataProvider *dataProvider; @property (nonatomic, strong) KBEmojiDataProvider *dataProvider;
@@ -59,7 +57,7 @@
[self addSubview:topBar]; [self addSubview:topBar];
self.backButton = [UIButton buttonWithType:UIButtonTypeSystem]; self.backButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.backButton.titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightSemibold]; self.backButton.titleLabel.font = [UIFont systemFontOfSize:30 weight:UIFontWeightSemibold];
[self.backButton setTitle:@"⌨︎" forState:UIControlStateNormal]; [self.backButton setTitle:@"⌨︎" forState:UIControlStateNormal];
[self.backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside]; [self.backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
[topBar addSubview:self.backButton]; [topBar addSubview:self.backButton];
@@ -97,9 +95,9 @@
[self.collectionView registerClass:KBEmojiCollectionCell.class forCellWithReuseIdentifier:@"KBEmojiCollectionCell"]; [self.collectionView registerClass:KBEmojiCollectionCell.class forCellWithReuseIdentifier:@"KBEmojiCollectionCell"];
[self addSubview:self.collectionView]; [self addSubview:self.collectionView];
self.bottomBar = [[UIView alloc] init]; self.bottomBar = [[KBEmojiBottomBarView alloc] init];
self.bottomBar.backgroundColor = [UIColor clearColor];
[self addSubview:self.bottomBar]; [self addSubview:self.bottomBar];
[self.bottomBar.deleteButton addTarget:self action:@selector(onDelete) forControlEvents:UIControlEventTouchUpInside];
// self.searchButton = [UIButton buttonWithType:UIButtonTypeSystem]; // self.searchButton = [UIButton buttonWithType:UIButtonTypeSystem];
// self.searchButton.layer.cornerRadius = 20; // self.searchButton.layer.cornerRadius = 20;
@@ -109,26 +107,6 @@
// [self.searchButton addTarget:self action:@selector(onSearch) forControlEvents:UIControlEventTouchUpInside]; // [self.searchButton addTarget:self action:@selector(onSearch) forControlEvents:UIControlEventTouchUpInside];
// [self.bottomBar addSubview:self.searchButton]; // [self.bottomBar addSubview:self.searchButton];
self.tabScrollView = [[UIScrollView alloc] init];
self.tabScrollView.showsHorizontalScrollIndicator = NO;
self.tabScrollView.backgroundColor = [UIColor clearColor];
[self.bottomBar addSubview:self.tabScrollView];
self.tabStackView = [[UIStackView alloc] init];
self.tabStackView.axis = UILayoutConstraintAxisHorizontal;
self.tabStackView.spacing = 8;
self.tabStackView.alignment = UIStackViewAlignmentFill;
[self.tabScrollView addSubview:self.tabStackView];
self.deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.deleteButton.layer.cornerRadius = 16;
self.deleteButton.layer.masksToBounds = YES;
self.deleteButton.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold];
[self.deleteButton setTitle:@"⌫" forState:UIControlStateNormal];
[self.deleteButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self.deleteButton addTarget:self action:@selector(onDelete) forControlEvents:UIControlEventTouchUpInside];
[self.bottomBar addSubview:self.deleteButton];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.mas_left).offset(12); make.left.equalTo(self.mas_left).offset(12);
make.right.equalTo(self.mas_right).offset(-12); make.right.equalTo(self.mas_right).offset(-12);
@@ -141,32 +119,6 @@
make.height.mas_equalTo(40); make.height.mas_equalTo(40);
}]; }];
// [self.searchButton mas_makeConstraints:^(MASConstraintMaker *make) {
// make.right.equalTo(self.bottomBar.mas_right).offset(-16);
// make.centerY.equalTo(self.bottomBar);
// make.width.mas_equalTo(84);
// make.height.mas_equalTo(40);
// }];
[self.tabScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.bottomBar.mas_left).offset(12);
make.right.equalTo(self.deleteButton.mas_left).offset(-12);
make.top.equalTo(self.bottomBar.mas_top).offset(4);
make.bottom.equalTo(self.bottomBar.mas_bottom).offset(-4);
}];
[self.tabStackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.tabScrollView);
make.height.equalTo(self.tabScrollView);
}];
[self.deleteButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.bottomBar.mas_right).offset(-12);
make.centerY.equalTo(self.bottomBar);
make.width.mas_equalTo(44);
make.height.equalTo(self.tabScrollView);
}];
UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipe:)]; UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipe:)];
leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft; leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft;
[self addGestureRecognizer:leftSwipe]; [self addGestureRecognizer:leftSwipe];
@@ -191,12 +143,13 @@
btn.layer.cornerCurve = kCACornerCurveContinuous; btn.layer.cornerCurve = kCACornerCurveContinuous;
} }
} }
if (self.deleteButton) { UIButton *deleteButton = self.bottomBar.deleteButton;
CGFloat radius = MIN(CGRectGetHeight(self.deleteButton.bounds), CGRectGetWidth(self.deleteButton.bounds)) / 2.0; if (deleteButton) {
CGFloat radius = MIN(CGRectGetHeight(deleteButton.bounds), CGRectGetWidth(deleteButton.bounds)) / 2.0;
if (radius > 0) { if (radius > 0) {
self.deleteButton.layer.cornerRadius = radius; deleteButton.layer.cornerRadius = radius;
if (@available(iOS 13.0, *)) { if (@available(iOS 13.0, *)) {
self.deleteButton.layer.cornerCurve = kCACornerCurveContinuous; deleteButton.layer.cornerCurve = kCACornerCurveContinuous;
} }
} }
} }
@@ -232,8 +185,10 @@
} }
- (void)rebuildTabButtons { - (void)rebuildTabButtons {
for (UIView *v in self.tabStackView.arrangedSubviews) { UIStackView *stackView = self.bottomBar.tabStackView;
[self.tabStackView removeArrangedSubview:v]; if (!stackView) { return; }
for (UIView *v in stackView.arrangedSubviews) {
[stackView removeArrangedSubview:v];
[v removeFromSuperview]; [v removeFromSuperview];
} }
NSMutableArray<UIButton *> *buttons = [NSMutableArray arrayWithCapacity:self.categories.count]; NSMutableArray<UIButton *> *buttons = [NSMutableArray arrayWithCapacity:self.categories.count];
@@ -248,8 +203,8 @@
[btn addTarget:self action:@selector(onTabTapped:) forControlEvents:UIControlEventTouchUpInside]; [btn addTarget:self action:@selector(onTabTapped:) forControlEvents:UIControlEventTouchUpInside];
btn.contentEdgeInsets = UIEdgeInsetsMake(0, 12, 0, 12); btn.contentEdgeInsets = UIEdgeInsetsMake(0, 12, 0, 12);
btn.translatesAutoresizingMaskIntoConstraints = NO; btn.translatesAutoresizingMaskIntoConstraints = NO;
// [btn.heightAnchor constraintEqualTo:self.tabScrollView.heightAnchor].active = YES; // [btn.heightAnchor constraintEqualTo:self.bottomBar.tabScrollView.heightAnchor].active = YES;
[self.tabStackView addArrangedSubview:btn]; [stackView addArrangedSubview:btn];
[buttons addObject:btn]; [buttons addObject:btn];
}]; }];
self.tabButtons = buttons.copy; self.tabButtons = buttons.copy;
@@ -287,10 +242,13 @@
- (void)scrollTabToVisible:(NSInteger)index { - (void)scrollTabToVisible:(NSInteger)index {
if (index < 0 || index >= self.tabButtons.count) return; if (index < 0 || index >= self.tabButtons.count) return;
UIScrollView *scrollView = self.bottomBar.tabScrollView;
UIStackView *stackView = self.bottomBar.tabStackView;
if (!scrollView || !stackView) { return; }
UIButton *btn = self.tabButtons[index]; UIButton *btn = self.tabButtons[index];
CGRect rect = [self.tabScrollView convertRect:btn.frame fromView:self.tabStackView]; CGRect rect = [scrollView convertRect:btn.frame fromView:stackView];
rect = CGRectInset(rect, -12, 0); rect = CGRectInset(rect, -12, 0);
[self.tabScrollView scrollRectToVisible:rect animated:YES]; [scrollView scrollRectToVisible:rect animated:YES];
} }
#pragma mark - Actions #pragma mark - Actions
@@ -351,10 +309,10 @@
self.tabNormalColor = [UIColor colorWithWhite:1 alpha:0.08]; self.tabNormalColor = [UIColor colorWithWhite:1 alpha:0.08];
self.tabSelectedColor = theme.accentColor ?: [UIColor colorWithWhite:1 alpha:0.25]; self.tabSelectedColor = theme.accentColor ?: [UIColor colorWithWhite:1 alpha:0.25];
[self updateTabHighlightStates]; [self updateTabHighlightStates];
if (self.deleteButton) { if (self.bottomBar.deleteButton) {
self.deleteButton.backgroundColor = self.tabNormalColor; self.bottomBar.deleteButton.backgroundColor = self.tabNormalColor;
UIColor *deleteTitleColor = theme.keyTextColor ?: [UIColor whiteColor]; UIColor *deleteTitleColor = theme.keyTextColor ?: [UIColor whiteColor];
[self.deleteButton setTitleColor:deleteTitleColor forState:UIControlStateNormal]; [self.bottomBar.deleteButton setTitleColor:deleteTitleColor forState:UIControlStateNormal];
} }
if (self.magnifierView) { if (self.magnifierView) {
self.magnifierView.backgroundColor = theme.keyBackground ?: [UIColor colorWithWhite:1 alpha:0.9]; self.magnifierView.backgroundColor = theme.keyBackground ?: [UIColor colorWithWhite:1 alpha:0.9];

View File

@@ -197,6 +197,7 @@
04FC970F2EB334F8007BD342 /* KBWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC970D2EB334F8007BD342 /* KBWebImageManager.m */; }; 04FC970F2EB334F8007BD342 /* KBWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC970D2EB334F8007BD342 /* KBWebImageManager.m */; };
04FEDAA12EEDB00100123456 /* KBEmojiDataProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDAA02EEDB00100123456 /* KBEmojiDataProvider.m */; }; 04FEDAA12EEDB00100123456 /* KBEmojiDataProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDAA02EEDB00100123456 /* KBEmojiDataProvider.m */; };
04FEDAB32EEDB05000123456 /* KBEmojiPanelView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDAB22EEDB05000123456 /* KBEmojiPanelView.m */; }; 04FEDAB32EEDB05000123456 /* KBEmojiPanelView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDAB22EEDB05000123456 /* KBEmojiPanelView.m */; };
04FEDB032EFE000000123456 /* KBEmojiBottomBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FEDB022EFE000000123456 /* KBEmojiBottomBarView.m */; };
471CAD3574798685B72ADD55 /* KBMyTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 180D662EC4DB3A7FFF83FF18 /* KBMyTheme.m */; }; 471CAD3574798685B72ADD55 /* KBMyTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 180D662EC4DB3A7FFF83FF18 /* KBMyTheme.m */; };
49B63DBAEE9076C591E13D68 /* KBShopThemeTagModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E2A844CD2D8584596DBE6316 /* KBShopThemeTagModel.m */; }; 49B63DBAEE9076C591E13D68 /* KBShopThemeTagModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E2A844CD2D8584596DBE6316 /* KBShopThemeTagModel.m */; };
550CB2630FA4A7B4B9782EFA /* KBMyTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 180D662EC4DB3A7FFF83FF18 /* KBMyTheme.m */; }; 550CB2630FA4A7B4B9782EFA /* KBMyTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 180D662EC4DB3A7FFF83FF18 /* KBMyTheme.m */; };
@@ -570,6 +571,8 @@
04FEDAA02EEDB00100123456 /* KBEmojiDataProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBEmojiDataProvider.m; sourceTree = "<group>"; }; 04FEDAA02EEDB00100123456 /* KBEmojiDataProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBEmojiDataProvider.m; sourceTree = "<group>"; };
04FEDAB12EEDB05000123456 /* KBEmojiPanelView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBEmojiPanelView.h; sourceTree = "<group>"; }; 04FEDAB12EEDB05000123456 /* KBEmojiPanelView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBEmojiPanelView.h; sourceTree = "<group>"; };
04FEDAB22EEDB05000123456 /* KBEmojiPanelView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBEmojiPanelView.m; sourceTree = "<group>"; }; 04FEDAB22EEDB05000123456 /* KBEmojiPanelView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBEmojiPanelView.m; sourceTree = "<group>"; };
04FEDB012EFE000000123456 /* KBEmojiBottomBarView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBEmojiBottomBarView.h; sourceTree = "<group>"; };
04FEDB022EFE000000123456 /* KBEmojiBottomBarView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBEmojiBottomBarView.m; sourceTree = "<group>"; };
180D662EC4DB3A7FFF83FF18 /* KBMyTheme.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyTheme.m; sourceTree = "<group>"; }; 180D662EC4DB3A7FFF83FF18 /* KBMyTheme.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyTheme.m; sourceTree = "<group>"; };
2C1092FB2B452F95B15D4263 /* Pods_CustomKeyboard.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CustomKeyboard.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 2C1092FB2B452F95B15D4263 /* Pods_CustomKeyboard.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CustomKeyboard.framework; sourceTree = BUILT_PRODUCTS_DIR; };
35E2B1C590E060D912A4E7F4 /* KBShopThemeTagModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBShopThemeTagModel.h; sourceTree = "<group>"; }; 35E2B1C590E060D912A4E7F4 /* KBShopThemeTagModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBShopThemeTagModel.h; sourceTree = "<group>"; };
@@ -1014,6 +1017,8 @@
children = ( children = (
04FEDAB12EEDB05000123456 /* KBEmojiPanelView.h */, 04FEDAB12EEDB05000123456 /* KBEmojiPanelView.h */,
04FEDAB22EEDB05000123456 /* KBEmojiPanelView.m */, 04FEDAB22EEDB05000123456 /* KBEmojiPanelView.m */,
04FEDB012EFE000000123456 /* KBEmojiBottomBarView.h */,
04FEDB022EFE000000123456 /* KBEmojiBottomBarView.m */,
0450AA722EF013D000B6AF06 /* KBEmojiCollectionCell.h */, 0450AA722EF013D000B6AF06 /* KBEmojiCollectionCell.h */,
0450AA732EF013D000B6AF06 /* KBEmojiCollectionCell.m */, 0450AA732EF013D000B6AF06 /* KBEmojiCollectionCell.m */,
); );
@@ -1812,6 +1817,7 @@
04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */, 04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */,
04FC95792EB09BC8007BD342 /* KBKeyBoardMainView.m in Sources */, 04FC95792EB09BC8007BD342 /* KBKeyBoardMainView.m in Sources */,
04FEDAB32EEDB05000123456 /* KBEmojiPanelView.m in Sources */, 04FEDAB32EEDB05000123456 /* KBEmojiPanelView.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 */,
04FC95732EB09570007BD342 /* KBFunctionBarView.m in Sources */, 04FC95732EB09570007BD342 /* KBFunctionBarView.m in Sources */,