键盘添加撤销操作

This commit is contained in:
2025-12-19 19:21:08 +08:00
parent 68306aa07f
commit 1c8834caf6
10 changed files with 332 additions and 15 deletions

View File

@@ -26,6 +26,7 @@
#import <MJExtension/MJExtension.h>
#import "KBBizCode.h"
#import "KBBackspaceLongPressHandler.h"
#import "KBBackspaceUndoManager.h"
@interface KBFunctionView () <KBFunctionBarViewDelegate, KBStreamOverlayViewDelegate, KBFunctionTagListViewDelegate>
// UI
@@ -769,6 +770,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
}
- (void)onTapDelete {
NSLog(@"点击:删除");
[[KBBackspaceUndoManager shared] registerNonClearAction];
UIInputViewController *ivc = KBFindInputViewController(self);
id<UITextDocumentProxy> proxy = ivc.textDocumentProxy;
[proxy deleteBackward];
@@ -779,6 +781,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
}
- (void)onTapSend {
NSLog(@"点击:发送");
[[KBBackspaceUndoManager shared] registerNonClearAction];
// App
UIInputViewController *ivc = KBFindInputViewController(self);
id<UITextDocumentProxy> proxy = ivc.textDocumentProxy;

View File

@@ -23,6 +23,8 @@ NS_ASSUME_NONNULL_BEGIN
/// 点击了右侧设置按钮
- (void)keyBoardMainViewDidTapSettings:(KBKeyBoardMainView *)keyBoardMainView;
/// 点击了撤销删除按钮
- (void)keyBoardMainViewDidTapUndo:(KBKeyBoardMainView *)keyBoardMainView;
/// emoji 视图里选择了一个表情
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didSelectEmoji:(NSString *)emoji;

View File

@@ -115,6 +115,12 @@
}
}
- (void)toolBarDidTapUndo:(KBToolBar *)toolBar {
if ([self.delegate respondsToSelector:@selector(keyBoardMainViewDidTapUndo:)]) {
[self.delegate keyBoardMainViewDidTapUndo:self];
}
}
#pragma mark - KBKeyboardViewDelegate
- (void)keyboardView:(KBKeyboardView *)keyboard didTapKey:(KBKey *)key {

View File

@@ -17,6 +17,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)toolBar:(KBToolBar *)toolBar didTapActionAtIndex:(NSInteger)index;
/// 右侧设置按钮点击
- (void)toolBarDidTapSettings:(KBToolBar *)toolBar;
/// 右侧撤销删除按钮点击
- (void)toolBarDidTapUndo:(KBToolBar *)toolBar;
@end
/// 顶部工具栏:左侧 4 个按钮,右侧 1 个设置按钮。
@@ -30,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
/// 暴露按钮以便外部定制(只读;首次访问时懒加载创建)
@property (nonatomic, strong, readonly) NSArray<UIButton *> *leftButtons;
@property (nonatomic, strong, readonly) UIButton *settingsButton;
@property (nonatomic, strong, readonly) UIButton *undoButton;
@end

View File

@@ -7,12 +7,16 @@
#import "KBToolBar.h"
#import "KBResponderUtils.h" // UIInputViewController
#import "KBBackspaceUndoManager.h"
@interface KBToolBar ()
@property (nonatomic, strong) UIView *leftContainer;
@property (nonatomic, strong) NSArray<UIButton *> *leftButtonsInternal;
//@property (nonatomic, strong) UIButton *settingsButtonInternal;
@property (nonatomic, strong) UIButton *globeButtonInternal; //
@property (nonatomic, strong) UIButton *undoButtonInternal; //
@property (nonatomic, assign) BOOL kbNeedsInputModeSwitchKey;
@property (nonatomic, assign) BOOL kbUndoVisible;
@end
@implementation KBToolBar
@@ -22,10 +26,18 @@
self.backgroundColor = [UIColor clearColor];
_leftButtonTitles = @[KBLocalized(@"Recharge Now")]; //
[self setupUI];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(kb_undoStateChanged)
name:KBBackspaceUndoStateDidChangeNotification
object:nil];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Public
@@ -33,6 +45,10 @@
return self.leftButtonsInternal;
}
- (UIButton *)undoButton {
return self.undoButtonInternal;
}
//- (UIButton *)settingsButton {
// return self.settingsButtonInternal;
//}
@@ -53,6 +69,7 @@
[self addSubview:self.leftContainer];
// [self addSubview:self.settingsButtonInternal];
[self addSubview:self.globeButtonInternal];
[self addSubview:self.undoButtonInternal];
//
// [self.settingsButtonInternal mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -68,14 +85,15 @@
make.width.height.mas_equalTo(32);
}];
//
[self.leftContainer mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.globeButtonInternal.mas_right).offset(8);
make.right.equalTo(self).offset(-12);
//
[self.undoButtonInternal mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.mas_right).offset(-12);
make.centerY.equalTo(self.mas_centerY);
make.height.mas_equalTo(32);
}];
[self kb_updateLeftContainerConstraints];
// =
NSMutableArray<UIButton *> *buttons = [NSMutableArray arrayWithCapacity:_leftButtonTitles.count];
UIView *previous = nil;
@@ -110,6 +128,7 @@
//
[self kb_refreshGlobeVisibility];
[self kb_updateUndoVisibilityAnimated:NO];
}
- (UIButton *)buildActionButtonAtIndex:(NSInteger)idx {
@@ -147,6 +166,12 @@
}
}
- (void)onUndo {
if ([self.delegate respondsToSelector:@selector(toolBarDidTapUndo:)]) {
[self.delegate toolBarDidTapUndo:self];
}
}
#pragma mark - Lazy
- (UIView *)leftContainer {
@@ -182,6 +207,23 @@
return _globeButtonInternal;
}
- (UIButton *)undoButtonInternal {
if (!_undoButtonInternal) {
_undoButtonInternal = [UIButton buttonWithType:UIButtonTypeSystem];
_undoButtonInternal.layer.cornerRadius = 16;
_undoButtonInternal.layer.masksToBounds = YES;
_undoButtonInternal.backgroundColor = [UIColor colorWithWhite:1 alpha:0.9];
_undoButtonInternal.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
[_undoButtonInternal setTitle:@"撤销删除" forState:UIControlStateNormal];
[_undoButtonInternal setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
_undoButtonInternal.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 10);
_undoButtonInternal.hidden = YES;
_undoButtonInternal.alpha = 0.0;
[_undoButtonInternal addTarget:self action:@selector(onUndo) forControlEvents:UIControlEventTouchUpInside];
}
return _undoButtonInternal;
}
#pragma mark - Globe (Input Mode Switch)
// 宿
@@ -193,18 +235,9 @@
}
self.globeButtonInternal.hidden = !needSwitchKey;
self.kbNeedsInputModeSwitchKey = needSwitchKey;
// leftContainer 12
[self.leftContainer mas_remakeConstraints:^(MASConstraintMaker *make) {
if (needSwitchKey) {
make.left.equalTo(self.globeButtonInternal.mas_right).offset(8);
} else {
make.left.equalTo(self.mas_left).offset(12);
}
make.right.equalTo(self).offset(-12);
make.centerY.equalTo(self.mas_centerY);
make.height.mas_equalTo(32);
}];
[self kb_updateLeftContainerConstraints];
//
//
@@ -220,6 +253,54 @@
}
}
- (void)kb_updateLeftContainerConstraints {
[self.leftContainer mas_remakeConstraints:^(MASConstraintMaker *make) {
if (self.kbNeedsInputModeSwitchKey) {
make.left.equalTo(self.globeButtonInternal.mas_right).offset(8);
} else {
make.left.equalTo(self.mas_left).offset(12);
}
if (self.kbUndoVisible) {
make.right.equalTo(self.undoButtonInternal.mas_left).offset(-8);
} else {
make.right.equalTo(self).offset(-12);
}
make.centerY.equalTo(self.mas_centerY);
make.height.mas_equalTo(32);
}];
}
- (void)kb_undoStateChanged {
[self kb_updateUndoVisibilityAnimated:YES];
}
- (void)kb_updateUndoVisibilityAnimated:(BOOL)animated {
BOOL visible = [KBBackspaceUndoManager shared].hasUndo;
if (self.kbUndoVisible == visible) { return; }
self.kbUndoVisible = visible;
self.undoButtonInternal.hidden = NO;
[self kb_updateLeftContainerConstraints];
void (^changes)(void) = ^{
self.undoButtonInternal.alpha = visible ? 1.0 : 0.0;
[self layoutIfNeeded];
};
void (^finish)(BOOL) = ^(BOOL finished) {
self.undoButtonInternal.hidden = !visible;
};
if (animated) {
[UIView animateWithDuration:0.18
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:changes
completion:finish];
} else {
changes();
finish(YES);
}
}
- (void)didMoveToWindow {
[super didMoveToWindow];
[self kb_refreshGlobeVisibility];