Files
keyboard/keyBoard/Class/Me/VC/KBMyKeyBoardVC.m
2025-11-10 21:33:00 +08:00

296 lines
12 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// KBMyKeyBoardVC.m
// keyBoard
//
// Created by Mac on 2025/11/10.
//
#import "KBMyKeyBoardVC.h"
#import "BMLongPressDragCellCollectionView.h"
#import "UICollectionViewLeftAlignedLayout.h"
#import "KBMyKeyboardCell.h"
#import "KBAlert.h"
/// 复用标识
static NSString * const kKBMyKeyboardCellId = @"kKBMyKeyboardCellId";
/// 截图页 - 自定义键盘管理
/// 要点:
/// 1使用 BMLongPressDragCellCollectionView 支持长按拖拽排序;
/// 2cell 宽度根据文案自适应;
/// 3全部使用 Masonry 进行布局,并采用懒加载创建控件;
@interface KBMyKeyBoardVC () <BMLongPressDragCellCollectionViewDelegate, BMLongPressDragCellCollectionViewDataSource>
// UI
@property (nonatomic, strong) UIView *sheetView; // 底部白色容器(圆角)
@property (nonatomic, strong) BMLongPressDragCellCollectionView *collectionView; // 可拖拽的列表
@property (nonatomic, strong) UIButton *saveButton; // 保存按钮
@property (nonatomic, strong) UIImageView *bgImageView; // 背景
// 数据源(必须是二维数组,库内部会在拖动时直接调整顺序)
@property (nonatomic, strong) NSMutableArray<NSMutableArray<NSDictionary *> *> *dataSourceArray; // {emoji,title}
@end
@interface KBMyKeyBoardVC ()
@end
@implementation KBMyKeyBoardVC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithHex:0xF6F8F9];
self.kb_navView.backgroundColor = [UIColor clearColor];
self.kb_titleLabel.text = @"My KeyBoard";
// 布局视图
[self.view insertSubview:self.bgImageView belowSubview:self.kb_navView];
[self.view addSubview:self.sheetView];
[self.sheetView addSubview:self.collectionView];
[self.view addSubview:self.saveButton];
[self.bgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.equalTo(self.view);
make.height.mas_equalTo(323);
}];
[self.sheetView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT + 60);
make.bottom.equalTo(self.view).offset(16);
}];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.top.equalTo(self.sheetView);
make.bottom.equalTo(self.saveButton.mas_top).offset(-15);
}];
[self.saveButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view).insets(UIEdgeInsetsMake(0, 24, 0, 24));
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-12);
make.height.mas_equalTo(50);
}];
// 初始数据
[self buildDefaultData];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 隐藏系统导航栏
// [self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// if (self.isMovingFromParentViewController || self.isBeingDismissed) {
// [self.navigationController setNavigationBarHidden:NO animated:animated];
// }
}
#pragma mark - Data
/// 构造示例数据(二维数组,仅 1 个 section
- (void)buildDefaultData {
NSArray *arr = @[
@{@"emoji":@"😊", @"title":@"Humor"},
@{@"emoji":@"😄", @"title":@"Jokes"},
@{@"emoji":@"🥰", @"title":@"Love"},
@{@"emoji":@"🤔", @"title":@"Thinking"},
@{@"emoji":@"🔥", @"title":@"Hot"},
@{@"emoji":@"🎉", @"title":@"Celebrate"},
@{@"emoji":@"🧠", @"title":@"Brainstorm"},
@{@"emoji":@"🐱", @"title":@"Cats"},
@{@"emoji":@"😂", @"title":@"LOL"},
@{@"emoji":@"📸", @"title":@"Photography"},
@{@"emoji":@"🌟", @"title":@"Star"},
@{@"emoji":@"🍀", @"title":@"Lucky"},
@{@"emoji":@"📚", @"title":@"Knowledge"},
@{@"emoji":@"🎵", @"title":@"Music"},
@{@"emoji":@"🚀", @"title":@"Launch"},
@{@"emoji":@"😊", @"title":@"Humor"},
@{@"emoji":@"😄", @"title":@"Jokes"},
@{@"emoji":@"🥰", @"title":@"Love"},
@{@"emoji":@"🤔", @"title":@"Thinking"},
@{@"emoji":@"🔥", @"title":@"Hot"},
@{@"emoji":@"🎉", @"title":@"Celebrate"},
@{@"emoji":@"🧠", @"title":@"Brainstorm"},
@{@"emoji":@"🐱", @"title":@"Cats"},
@{@"emoji":@"😂", @"title":@"LOL"},
@{@"emoji":@"📸", @"title":@"Photography"},
@{@"emoji":@"🌟", @"title":@"Star"},
@{@"emoji":@"🍀", @"title":@"Lucky"},
@{@"emoji":@"📚", @"title":@"Knowledge"},
@{@"emoji":@"🎵", @"title":@"Music"},
@{@"emoji":@"🚀", @"title":@"Launch"},
@{@"emoji":@"😊", @"title":@"Humor"},
@{@"emoji":@"😄", @"title":@"Jokes"},
@{@"emoji":@"🥰", @"title":@"Love"},
@{@"emoji":@"🤔", @"title":@"Thinking"},
@{@"emoji":@"🔥", @"title":@"Hot"},
@{@"emoji":@"🎉", @"title":@"Celebrate"},
@{@"emoji":@"🧠", @"title":@"Brainstorm"},
@{@"emoji":@"🐱", @"title":@"Cats"},
@{@"emoji":@"😂", @"title":@"LOL"},
@{@"emoji":@"📸", @"title":@"Photography"},
@{@"emoji":@"🌟", @"title":@"Star"},
@{@"emoji":@"🍀", @"title":@"Lucky"},
@{@"emoji":@"📚", @"title":@"Knowledge"},
@{@"emoji":@"🎵", @"title":@"Music"},
@{@"emoji":@"🚀", @"title":@"Launch"},
];
self.dataSourceArray = [@[[arr mutableCopy]] mutableCopy];
[self.collectionView reloadData];
}
#pragma mark - BMLongPressDragCellCollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return self.dataSourceArray.count; }
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.dataSourceArray[section].count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
KBMyKeyboardCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kKBMyKeyboardCellId forIndexPath:indexPath];
NSDictionary *d = self.dataSourceArray[indexPath.section][indexPath.item];
[cell configEmoji:d[@"emoji"] title:d[@"title"]];
__weak typeof(self) weakSelf = self;
__weak typeof(collectionView) weakCV = collectionView;
cell.onMinusTapped = ^(KBMyKeyboardCell * _Nonnull tappedCell) {
__strong typeof(weakSelf) self = weakSelf;
if (!self) { return; }
NSIndexPath *tapIndexPath = [weakCV indexPathForCell:tappedCell];
if (!tapIndexPath) { return; }
// [KBAlert confirmTitle:@"删除该标签?" message:@"删除后不可恢复" completion:^(BOOL ok) {
// if (!ok) { return; }
// // 更新数据源并删除 item
// if (tapIndexPath.section < self.dataSourceArray.count) {
// NSMutableArray *section = self.dataSourceArray[tapIndexPath.section];
// if (tapIndexPath.item < section.count) {
// [section removeObjectAtIndex:tapIndexPath.item];
// [self.collectionView performBatchUpdates:^{
// [self.collectionView deleteItemsAtIndexPaths:@[tapIndexPath]];
// } completion:nil];
// }
// }
// }];
[KBAlert confirmTitle:@"删除该标签?"
message:@"删除后不可恢复"
ok:@"确定"
cancel:@"取消"
okColor:[UIColor redColor]
cancelColor:[UIColor blackColor]
completion:^(BOOL ok) {
if (!ok) { return; }
// 更新数据源并删除 item
if (tapIndexPath.section < self.dataSourceArray.count) {
NSMutableArray *section = self.dataSourceArray[tapIndexPath.section];
if (tapIndexPath.item < section.count) {
[section removeObjectAtIndex:tapIndexPath.item];
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:@[tapIndexPath]];
} completion:nil];
}
}
}];
};
return cell;
}
// 拖拽库要求实现:返回当前“二维数组”数据源
- (NSArray<NSArray<id> *> *)dataSourceWithDragCellCollectionView:(__kindof BMLongPressDragCellCollectionView *)dragCellCollectionView {
return self.dataSourceArray;
}
// 拖拽后回调:保存最新数据
- (void)dragCellCollectionView:(BMLongPressDragCellCollectionView *)dragCellCollectionView newDataArrayAfterMove:(nullable NSArray<NSArray<id> *> *)newDataArray {
self.dataSourceArray = [newDataArray mutableCopy];
}
#pragma mark - BMLongPressDragCellCollectionViewDelegate (布局)
// 根据文案长度动态返回 item 尺寸
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *d = self.dataSourceArray[indexPath.section][indexPath.item];
return [KBMyKeyboardCell sizeForEmoji:d[@"emoji"] title:d[@"title"]];
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(12, 12, 12, 12);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section { return 10; }
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { return 10; }
#pragma mark - Actions
- (void)onSave {
// 这里只做示意:保存当前顺序
NSLog(@"保存顺序: %@", self.dataSourceArray);
[KBHUD showInfo:@"已保存"];
}
#pragma mark - Lazy UI
//- (UILabel *)titleLabel {
// if (!_titleLabel) {
// _titleLabel = [UILabel new];
// _titleLabel.text = @"My Keyboard"; // 顶部标题
// _titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold];
// _titleLabel.textColor = [UIColor colorWithHex:0x1B1F1A];
// }
// return _titleLabel;
//}
- (UIView *)sheetView {
if (!_sheetView) {
_sheetView = [UIView new];
_sheetView.backgroundColor = [UIColor whiteColor];
_sheetView.layer.cornerRadius = 32.0;
_sheetView.layer.masksToBounds = YES;
}
return _sheetView;
}
- (BMLongPressDragCellCollectionView *)collectionView {
if (!_collectionView) {
UICollectionViewLeftAlignedLayout *layout = [UICollectionViewLeftAlignedLayout new];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
// layout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16);
_collectionView = [[BMLongPressDragCellCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
_collectionView.backgroundColor = [UIColor clearColor];
_collectionView.delegate = self; // 注意:代理为 BMLongPressDragCellCollectionViewDelegate
_collectionView.dataSource = self; // 注意:数据源为 BMLongPressDragCellCollectionViewDataSource
_collectionView.alwaysBounceVertical = YES;
_collectionView.showsVerticalScrollIndicator = NO;
[_collectionView registerClass:KBMyKeyboardCell.class forCellWithReuseIdentifier:kKBMyKeyboardCellId];
}
return _collectionView;
}
- (UIButton *)saveButton {
if (!_saveButton) {
_saveButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_saveButton setTitle:@"Save" forState:UIControlStateNormal];
_saveButton.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold];
[_saveButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_saveButton.backgroundColor = [UIColor colorWithHex:KBColorValue];
_saveButton.layer.cornerRadius = 25;
_saveButton.layer.masksToBounds = YES;
[_saveButton addTarget:self action:@selector(onSave) forControlEvents:UIControlEventTouchUpInside];
}
return _saveButton;
}
- (UIImageView *)bgImageView{
if (!_bgImageView) {
_bgImageView = [[UIImageView alloc] init];
_bgImageView.image = [UIImage imageNamed:@"my_keyboard_bg"];
}
return _bgImageView;
}
@end