Fix KBAICommentInputView弹出位置

This commit is contained in:
2026-02-25 17:13:25 +08:00
parent 851c0d9531
commit 92ca5c6180
3 changed files with 156 additions and 8 deletions

Submodule _spm/checkouts/swift-collections added at 7b847a3b70

View File

@@ -92,7 +92,9 @@
}
- (void)showKeyboard {
[self.textField becomeFirstResponder];
BOOL before = self.textField.isFirstResponder;
BOOL become = [self.textField becomeFirstResponder];
NSLog(@"[KBAICommentInputView] showKeyboard before=%d become=%d after=%d", before, become, self.textField.isFirstResponder);
}
#pragma mark - Actions
@@ -129,11 +131,17 @@
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
NSLog(@"[KBAICommentInputView] textFieldShouldBeginEditing");
[self updatePlaceholderVisibility];
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
NSLog(@"[KBAICommentInputView] textFieldDidBeginEditing firstResponder=%d", textField.isFirstResponder);
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
NSLog(@"[KBAICommentInputView] textFieldDidEndEditing");
[self updatePlaceholderVisibility];
}

View File

@@ -167,6 +167,8 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self kb_syncTextInputStateIfNeeded];
[self kb_logInputLayoutWithTag:@"viewDidAppear"];
KBPersonaChatCell *cell = [self currentPersonaCell];
if (cell) {
[cell onBecameCurrentPersonaCell];
@@ -175,6 +177,17 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// hidden/firstResponder
[self.view endEditing:YES];
self.voiceInputKeyboardActive = NO;
self.currentKeyboardHeight = 0.0;
self.isTextInputMode = NO;
self.commentInputView.hidden = YES;
[self.commentInputBottomConstraint setOffset:100];
self.voiceInputBar.hidden = NO;
[self.voiceInputBarBottomConstraint setOffset:-self.baseInputBarBottomSpacing];
[self.view layoutIfNeeded];
[self kb_logInputLayoutWithTag:@"viewWillDisappear"];
for (NSIndexPath *indexPath in self.collectionView.indexPathsForVisibleItems) {
KBPersonaChatCell *cell = (KBPersonaChatCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
if (cell) {
@@ -263,16 +276,26 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
self.isTextInputMode = YES;
self.voiceInputBar.hidden = YES;
self.commentInputView.hidden = NO;
[self kb_logInputLayoutWithTag:@"showTextInputView-beforeAdjust"];
//
// 使
CGFloat targetOffset = self.currentKeyboardHeight > 0.0 ? -self.currentKeyboardHeight : -self.baseInputBarBottomSpacing;
[self.commentInputBottomConstraint setOffset:targetOffset];
[self.view layoutIfNeeded];
[self kb_logInputLayoutWithTag:@"showTextInputView-afterAdjust"];
[self.commentInputView showKeyboard];
}
///
- (void)hideTextInputView {
[self kb_logInputLayoutWithTag:@"hideTextInputView-before"];
self.isTextInputMode = NO;
[self.view endEditing:YES];
[self.commentInputView clearText];
self.commentInputView.hidden = YES;
[self.commentInputBottomConstraint setOffset:100];
self.voiceInputBar.hidden = NO;
[self kb_logInputLayoutWithTag:@"hideTextInputView-after"];
}
#pragma mark - 2
@@ -570,12 +593,32 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
- (void)setupKeyboardNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleKeyboardWillChangeFrame:)
selector:@selector(handleKeyboardNotification:)
name:UIKeyboardWillChangeFrameNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleKeyboardNotification:)
name:UIKeyboardDidChangeFrameNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleKeyboardNotification:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleKeyboardNotification:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleKeyboardNotification:)
name:UIKeyboardWillHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleKeyboardNotification:)
name:UIKeyboardDidHideNotification
object:nil];
}
- (void)handleKeyboardWillChangeFrame:(NSNotification *)notification {
- (void)handleKeyboardNotification:(NSNotification *)notification {
NSDictionary *userInfo = notification.userInfo;
CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
@@ -583,17 +626,42 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
CGRect convertedFrame = [self.view convertRect:endFrame fromView:nil];
CGFloat keyboardHeight = MAX(0.0, CGRectGetMaxY(self.view.bounds) - CGRectGetMinY(convertedFrame));
BOOL shouldHandle = YES;
BOOL fromAllowedInput = [self kb_isKeyboardFromVoiceInputBar];
if (keyboardHeight > 0.0) {
if (![self kb_isKeyboardFromVoiceInputBar]) {
return;
// firstResponder
if (!self.isTextInputMode && !fromAllowedInput) {
shouldHandle = NO;
}
self.voiceInputKeyboardActive = YES;
} else {
if (!self.voiceInputKeyboardActive) {
return;
if (!self.voiceInputKeyboardActive && !self.isTextInputMode) {
shouldHandle = NO;
}
self.voiceInputKeyboardActive = NO;
}
[self kb_logKeyboardNotification:notification
keyboardHeight:keyboardHeight
convertedFrame:convertedFrame
fromAllowedInput:fromAllowedInput
shouldHandle:shouldHandle];
if (!shouldHandle) {
return;
}
UIView *firstResponder = [self kb_findFirstResponderInView:self.view];
BOOL firstInComment = firstResponder ? [firstResponder isDescendantOfView:self.commentInputView] : NO;
if (keyboardHeight > 0.0 && firstInComment && !self.isTextInputMode) {
// firstResponder commentInput textMode NO
self.isTextInputMode = YES;
self.voiceInputBar.hidden = YES;
self.commentInputView.hidden = NO;
[self kb_logInputLayoutWithTag:@"keyboardSync-forceTextMode"];
}
if (keyboardHeight <= 0.0) {
// VoiceInputBar
if (self.isTextInputMode) {
[self hideTextInputView];
@@ -625,7 +693,9 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
animations:^{
[self.view layoutIfNeeded];
}
completion:nil];
completion:^(BOOL finished) {
[self kb_logInputLayoutWithTag:@"handleKeyboardNotification-animComplete"];
}];
}
#pragma mark - 7
@@ -843,6 +913,7 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
}
- (void)chatLimitPopViewDidTapRecharge:(KBChatLimitPopView *)view {
NSLog(@"[KBAIHomeVC][Pay] chatLimitPopViewDidTapRecharge");
[self.chatLimitPopView dismiss];
if (![KBUserSessionManager shared].isLoggedIn) {
[[KBUserSessionManager shared] goLoginVC];
@@ -961,6 +1032,74 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
[self showPersonaSidebar];
}
#pragma mark - Debug Log
- (void)kb_syncTextInputStateIfNeeded {
UIView *firstResponder = [self kb_findFirstResponderInView:self.view];
BOOL firstInComment = firstResponder ? [firstResponder isDescendantOfView:self.commentInputView] : NO;
if (!firstInComment) {
return;
}
self.isTextInputMode = YES;
self.voiceInputBar.hidden = YES;
self.commentInputView.hidden = NO;
if (self.currentKeyboardHeight > 0.0) {
[self.commentInputBottomConstraint setOffset:-self.currentKeyboardHeight];
[self.voiceInputBarBottomConstraint setOffset:-MAX(self.currentKeyboardHeight - 5.0, self.baseInputBarBottomSpacing)];
} else {
[self.commentInputBottomConstraint setOffset:-self.baseInputBarBottomSpacing];
}
[self.view layoutIfNeeded];
[self kb_logInputLayoutWithTag:@"kb_syncTextInputStateIfNeeded"];
}
- (void)kb_logInputLayoutWithTag:(NSString *)tag {
[self.view layoutIfNeeded];
UIView *firstResponder = [self kb_findFirstResponderInView:self.view];
NSString *firstResponderInfo = firstResponder ? NSStringFromClass(firstResponder.class) : @"nil";
NSLog(@"[KBAIHomeVC][Layout][%@] textMode=%d voiceHidden=%d commentHidden=%d currentKeyboardHeight=%.2f viewH=%.2f safeBottom=%.2f commentFrame=%@ voiceFrame=%@ firstResponder=%@",
tag ?: @"-",
self.isTextInputMode,
self.voiceInputBar.hidden,
self.commentInputView.hidden,
self.currentKeyboardHeight,
CGRectGetHeight(self.view.bounds),
self.view.safeAreaInsets.bottom,
NSStringFromCGRect(self.commentInputView.frame),
NSStringFromCGRect(self.voiceInputBar.frame),
firstResponderInfo);
}
- (void)kb_logKeyboardNotification:(NSNotification *)notification
keyboardHeight:(CGFloat)keyboardHeight
convertedFrame:(CGRect)convertedFrame
fromAllowedInput:(BOOL)fromAllowedInput
shouldHandle:(BOOL)shouldHandle {
NSDictionary *userInfo = notification.userInfo;
CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
NSInteger curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
UIView *firstResponder = [self kb_findFirstResponderInView:self.view];
NSString *firstResponderInfo = firstResponder ? NSStringFromClass(firstResponder.class) : @"nil";
BOOL firstInComment = firstResponder ? [firstResponder isDescendantOfView:self.commentInputView] : NO;
BOOL firstInVoice = firstResponder ? [firstResponder isDescendantOfView:self.voiceInputBar] : NO;
NSLog(@"[KBAIHomeVC][Keyboard][%@] shouldHandle=%d textMode=%d voiceActive=%d fromAllowed=%d firstInComment=%d firstInVoice=%d firstResponder=%@ endFrame=%@ converted=%@ keyboardHeight=%.2f duration=%.2f curve=%ld viewWindow=%@",
notification.name,
shouldHandle,
self.isTextInputMode,
self.voiceInputKeyboardActive,
fromAllowedInput,
firstInComment,
firstInVoice,
firstResponderInfo,
NSStringFromCGRect(endFrame),
NSStringFromCGRect(convertedFrame),
keyboardHeight,
duration,
(long)curve,
self.view.window ? @"YES" : @"NO");
}
- (void)showPersonaSidebar {
if (!self.sidebarView) {
CGFloat width = KB_SCREEN_WIDTH * 0.7;