新增删除弹窗,修改bug
This commit is contained in:
@@ -10,12 +10,14 @@
|
||||
#import "KBChattedCompanionModel.h"
|
||||
#import "KBHUD.h"
|
||||
#import "KBAIChatMessageCacheManager.h"
|
||||
#import "KBAIChatDeleteConfirmView.h"
|
||||
#import "LSTPopView.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
|
||||
/// 聊天会话被重置的通知
|
||||
static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidResetNotification";
|
||||
|
||||
@interface KBAIMessageChatingVC ()
|
||||
@interface KBAIMessageChatingVC () <KBAIChatDeleteConfirmViewDelegate, UIGestureRecognizerDelegate>
|
||||
|
||||
@property (nonatomic, strong) AiVM *viewModel;
|
||||
@property (nonatomic, strong) NSMutableArray<KBChattedCompanionModel *> *chattedList;
|
||||
@@ -24,6 +26,16 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
||||
@property (nonatomic, strong) UIButton *deleteButton;
|
||||
/// 当前长按的 indexPath
|
||||
@property (nonatomic, strong) NSIndexPath *longPressIndexPath;
|
||||
/// 长按手势
|
||||
@property (nonatomic, strong) UILongPressGestureRecognizer *longPressGesture;
|
||||
/// 单击手势(用于隐藏删除按钮)
|
||||
@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;
|
||||
/// 删除按钮显示代数(用于避免旧的隐藏动画 completion 误删新按钮)
|
||||
@property (nonatomic, assign) NSInteger deleteButtonGeneration;
|
||||
/// 待删除的 indexPath(弹窗确认使用)
|
||||
@property (nonatomic, strong) NSIndexPath *pendingDeleteIndexPath;
|
||||
/// 删除确认弹窗
|
||||
@property (nonatomic, weak) LSTPopView *deleteConfirmPopView;
|
||||
|
||||
@end
|
||||
|
||||
@@ -39,23 +51,53 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
||||
[self setupLongPressGesture];
|
||||
|
||||
// 添加点击手势,用于隐藏删除按钮
|
||||
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
|
||||
tapGesture.cancelsTouchesInView = NO; // 不影响 cell 的点击
|
||||
[self.tableView addGestureRecognizer:tapGesture];
|
||||
self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
|
||||
self.tapGesture.cancelsTouchesInView = NO; // 不影响 cell 的点击
|
||||
self.tapGesture.delegate = self;
|
||||
if (self.longPressGesture) {
|
||||
[self.tapGesture requireGestureRecognizerToFail:self.longPressGesture];
|
||||
}
|
||||
[self.tableView addGestureRecognizer:self.tapGesture];
|
||||
}
|
||||
|
||||
#pragma mark - UIGestureRecognizerDelegate
|
||||
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
|
||||
// 删除按钮显示时,点击按钮本身不走 tableView 的 tap 逻辑
|
||||
if (gestureRecognizer == self.tapGesture) {
|
||||
if (self.deleteButton && !self.deleteButton.hidden) {
|
||||
CGPoint p = [touch locationInView:self.deleteButton];
|
||||
if (CGRectContainsPoint(self.deleteButton.bounds, p)) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - 手势处理
|
||||
|
||||
- (void)setupLongPressGesture {
|
||||
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
|
||||
longPress.minimumPressDuration = 0.5; // 长按0.5秒
|
||||
[self.tableView addGestureRecognizer:longPress];
|
||||
self.longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
|
||||
self.longPressGesture.minimumPressDuration = 0.5; // 长按0.5秒
|
||||
self.longPressGesture.delegate = self;
|
||||
[self.tableView addGestureRecognizer:self.longPressGesture];
|
||||
}
|
||||
|
||||
- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture {
|
||||
CGPoint point = [gesture locationInView:self.tableView];
|
||||
NSLog(@"[KBAIMessageChatingVC] longPress state=%ld point=(%.1f, %.1f)",
|
||||
(long)gesture.state, point.x, point.y);
|
||||
|
||||
if (gesture.state == UIGestureRecognizerStateBegan) {
|
||||
CGPoint point = [gesture locationInView:self.tableView];
|
||||
// 关键:长按期间禁用 tap,避免同一轮触摸结束被识别为 tap 导致“闪一下就隐藏”
|
||||
if (self.tapGesture.enabled) {
|
||||
self.tapGesture.enabled = NO;
|
||||
NSLog(@"[KBAIMessageChatingVC] tapGesture disabled for longPress");
|
||||
}
|
||||
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point];
|
||||
NSLog(@"[KBAIMessageChatingVC] longPress began indexPath=%@",
|
||||
indexPath);
|
||||
|
||||
if (indexPath) {
|
||||
// 在手指位置显示删除按钮
|
||||
@@ -64,12 +106,23 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
||||
// 在 showDeleteButtonAtPoint 之后再设置,避免被 hideDeleteButton 清空
|
||||
self.longPressIndexPath = indexPath;
|
||||
}
|
||||
} else if (gesture.state == UIGestureRecognizerStateEnded ||
|
||||
gesture.state == UIGestureRecognizerStateCancelled ||
|
||||
gesture.state == UIGestureRecognizerStateFailed) {
|
||||
if (!self.tapGesture.enabled) {
|
||||
self.tapGesture.enabled = YES;
|
||||
NSLog(@"[KBAIMessageChatingVC] tapGesture re-enabled after longPress");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleTapGesture:(UITapGestureRecognizer *)gesture {
|
||||
// 点击其他地方隐藏删除按钮
|
||||
if (self.deleteButton && !self.deleteButton.hidden) {
|
||||
CGPoint pointInView = [gesture locationInView:self.tableView];
|
||||
NSLog(@"[KBAIMessageChatingVC] tap state=%ld point=(%.1f, %.1f)",
|
||||
(long)gesture.state, pointInView.x, pointInView.y);
|
||||
|
||||
CGPoint pointInButton = [gesture locationInView:self.deleteButton];
|
||||
|
||||
// 如果点击的不是删除按钮,则隐藏
|
||||
@@ -83,8 +136,10 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
||||
}
|
||||
|
||||
- (void)showDeleteButtonAtPoint:(CGPoint)point {
|
||||
// 隐藏之前的按钮
|
||||
[self hideDeleteButton];
|
||||
// 新一轮展示:使之前的隐藏动画 completion 失效
|
||||
self.deleteButtonGeneration += 1;
|
||||
NSLog(@"[KBAIMessageChatingVC] showDeleteButtonAtPoint=(%.1f, %.1f) generation=%ld",
|
||||
point.x, point.y, (long)self.deleteButtonGeneration);
|
||||
|
||||
// 创建删除按钮
|
||||
if (!self.deleteButton) {
|
||||
@@ -105,7 +160,14 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
||||
}
|
||||
|
||||
// 添加到父视图(确保在最上层)
|
||||
[self.view addSubview:self.deleteButton];
|
||||
if (self.deleteButton.superview != self.view) {
|
||||
[self.view addSubview:self.deleteButton];
|
||||
} else {
|
||||
[self.view bringSubviewToFront:self.deleteButton];
|
||||
}
|
||||
|
||||
// 取消隐藏动画,避免闪一下
|
||||
[self.deleteButton.layer removeAllAnimations];
|
||||
|
||||
// 设置按钮大小和位置
|
||||
CGSize buttonSize = CGSizeMake(110, 40);
|
||||
@@ -138,6 +200,9 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
||||
}];
|
||||
|
||||
self.deleteButton.hidden = NO;
|
||||
self.deleteButton.alpha = 1.0;
|
||||
self.deleteButton.transform = CGAffineTransformIdentity;
|
||||
NSLog(@"[KBAIMessageChatingVC] deleteButton shown");
|
||||
|
||||
// 添加弹出动画
|
||||
self.deleteButton.transform = CGAffineTransformMakeScale(0.3, 0.3);
|
||||
@@ -150,10 +215,20 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
||||
|
||||
- (void)hideDeleteButton {
|
||||
if (self.deleteButton) {
|
||||
NSInteger generation = self.deleteButtonGeneration;
|
||||
NSLog(@"[KBAIMessageChatingVC] hideDeleteButton generation=%ld", (long)generation);
|
||||
// 取消之前的动画,避免叠加
|
||||
[self.deleteButton.layer removeAllAnimations];
|
||||
[UIView animateWithDuration:0.15 animations:^{
|
||||
self.deleteButton.alpha = 0;
|
||||
self.deleteButton.transform = CGAffineTransformMakeScale(0.8, 0.8);
|
||||
} completion:^(BOOL finished) {
|
||||
// 如果期间又展示了新一轮按钮,则不执行移除(避免“闪一下”)
|
||||
if (generation != self.deleteButtonGeneration) {
|
||||
NSLog(@"[KBAIMessageChatingVC] hide completion ignored (generation changed: %ld -> %ld)",
|
||||
(long)generation, (long)self.deleteButtonGeneration);
|
||||
return;
|
||||
}
|
||||
self.deleteButton.hidden = YES;
|
||||
[self.deleteButton removeFromSuperview];
|
||||
}];
|
||||
@@ -166,26 +241,69 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存 indexPath,因为后面会清空
|
||||
NSIndexPath *indexPath = self.longPressIndexPath;
|
||||
// 保存 indexPath,因为 hideDeleteButton 会清空
|
||||
self.pendingDeleteIndexPath = self.longPressIndexPath;
|
||||
[self hideDeleteButton];
|
||||
[self showDeleteConfirmPopView];
|
||||
}
|
||||
|
||||
#pragma mark - 删除确认弹窗
|
||||
|
||||
- (void)showDeleteConfirmPopView {
|
||||
if (self.deleteConfirmPopView) {
|
||||
[self.deleteConfirmPopView dismiss];
|
||||
}
|
||||
|
||||
CGFloat width = KB_SCREEN_WIDTH - 80;
|
||||
KBAIChatDeleteConfirmView *content = [[KBAIChatDeleteConfirmView alloc] initWithFrame:CGRectMake(0, 0, width, 260)];
|
||||
content.delegate = self;
|
||||
|
||||
LSTPopView *popView = [LSTPopView initWithCustomView:content
|
||||
parentView:nil
|
||||
popStyle:LSTPopStyleFade
|
||||
dismissStyle:LSTDismissStyleFade];
|
||||
popView.bgColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
|
||||
popView.hemStyle = LSTHemStyleCenter;
|
||||
popView.isClickBgDismiss = YES;
|
||||
popView.isAvoidKeyboard = NO;
|
||||
self.deleteConfirmPopView = popView;
|
||||
[popView pop];
|
||||
}
|
||||
|
||||
#pragma mark - KBAIChatDeleteConfirmViewDelegate
|
||||
|
||||
- (void)chatDeleteConfirmViewDidTapDelete:(KBAIChatDeleteConfirmView *)view {
|
||||
[self.deleteConfirmPopView dismiss];
|
||||
NSIndexPath *indexPath = self.pendingDeleteIndexPath;
|
||||
self.pendingDeleteIndexPath = nil;
|
||||
[self performDeleteAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (void)chatDeleteConfirmViewDidTapCancel:(KBAIChatDeleteConfirmView *)view {
|
||||
[self.deleteConfirmPopView dismiss];
|
||||
self.pendingDeleteIndexPath = nil;
|
||||
}
|
||||
|
||||
#pragma mark - 删除逻辑
|
||||
|
||||
- (void)performDeleteAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (!indexPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取要删除的数据
|
||||
if (indexPath.row >= self.chattedList.count) {
|
||||
NSLog(@"[KBAIMessageChatingVC] 错误:索引越界,row=%ld, count=%ld",
|
||||
NSLog(@"[KBAIMessageChatingVC] 错误:索引越界,row=%ld, count=%ld",
|
||||
(long)indexPath.row, (long)self.chattedList.count);
|
||||
[self hideDeleteButton];
|
||||
return;
|
||||
}
|
||||
|
||||
KBChattedCompanionModel *model = self.chattedList[indexPath.row];
|
||||
NSInteger companionId = model.companionId;
|
||||
|
||||
NSLog(@"[KBAIMessageChatingVC] 开始删除聊天记录:companionId=%ld, name=%@",
|
||||
NSLog(@"[KBAIMessageChatingVC] 开始删除聊天记录:companionId=%ld, name=%@",
|
||||
(long)companionId, model.name);
|
||||
|
||||
// 隐藏删除按钮
|
||||
[self hideDeleteButton];
|
||||
|
||||
// 显示加载提示
|
||||
[KBHUD show];
|
||||
|
||||
@@ -214,7 +332,7 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
||||
}
|
||||
|
||||
// 2. 更新 TableView(带动画)
|
||||
[weakSelf.tableView deleteRowsAtIndexPaths:@[indexPath]
|
||||
[weakSelf.tableView deleteRowsAtIndexPaths:@[indexPath]
|
||||
withRowAnimation:UITableViewRowAnimationLeft];
|
||||
|
||||
// 3. ✅ 清除缓存管理器中的聊天记录(关键!)
|
||||
|
||||
Reference in New Issue
Block a user