From 674f09d5b6faf2c391fe39dbab715a915e440fbf Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Thu, 8 Jan 2026 20:18:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86=E6=8C=89=E9=92=AE=E4=B9=8B?= =?UTF-8?q?=E9=97=B4=E7=82=B9=E4=B8=8D=E5=88=B0=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20=20HitInside?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CustomKeyboard/View/KBKeyboardView.m | 55 +++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/CustomKeyboard/View/KBKeyboardView.m b/CustomKeyboard/View/KBKeyboardView.m index 61c57fc..7919ef8 100644 --- a/CustomKeyboard/View/KBKeyboardView.m +++ b/CustomKeyboard/View/KBKeyboardView.m @@ -135,27 +135,42 @@ static const CGFloat kKBLettersRow2EdgeSpacerMultiplier = 0.5; if ([hit isKindOfClass:[KBKeyButton class]]) { return hit; } - if (hit == self || hit == self.row1 || hit == self.row2 || hit == self.row3 || hit == self.row4) { + if ([self kb_isHitInsideKeyRows:hit]) { KBKeyButton *btn = [self kb_nearestKeyButtonForPoint:point]; if (btn) { return btn; } } return hit; } +- (BOOL)kb_isHitInsideKeyRows:(UIView *)hitView { + if (!hitView) { return NO; } + if (hitView == self) { return YES; } + if ([hitView isDescendantOfView:self.row1]) { return YES; } + if ([hitView isDescendantOfView:self.row2]) { return YES; } + if ([hitView isDescendantOfView:self.row3]) { return YES; } + if ([hitView isDescendantOfView:self.row4]) { return YES; } + return NO; +} + - (KBKeyButton *)kb_nearestKeyButtonForPoint:(CGPoint)point { - // 扩大按键的可点击区域,优先响应间隙点击(贴近系统键盘手感)。 - CGFloat slopX = KBFit(8.0f); - CGFloat slopY = KBFit(4.0f); KBKeyButton *best = nil; CGFloat bestDistance = CGFLOAT_MAX; NSArray *rows = @[self.row1, self.row2, self.row3, self.row4]; + + UIView *targetRow = nil; for (UIView *row in rows) { - for (UIView *view in row.subviews) { - if (![view isKindOfClass:[KBKeyButton class]]) { continue; } - KBKeyButton *btn = (KBKeyButton *)view; - CGRect frame = [self convertRect:btn.frame fromView:row]; - CGRect hitFrame = CGRectInset(frame, -slopX, -slopY); - if (!CGRectContainsPoint(hitFrame, point)) { continue; } + CGRect rowFrame = [self convertRect:row.bounds fromView:row]; + if (CGRectContainsPoint(rowFrame, point)) { + targetRow = row; + break; + } + } + + NSArray *candidateRows = targetRow ? @[targetRow] : rows; + for (UIView *row in candidateRows) { + NSArray *buttons = [self kb_collectKeyButtonsInView:row]; + for (KBKeyButton *btn in buttons) { + CGRect frame = [self convertRect:btn.frame fromView:btn.superview]; CGFloat dx = point.x - CGRectGetMidX(frame); CGFloat dy = point.y - CGRectGetMidY(frame); CGFloat dist = (dx * dx) + (dy * dy); @@ -168,6 +183,26 @@ static const CGFloat kKBLettersRow2EdgeSpacerMultiplier = 0.5; return best; } +- (NSArray *)kb_collectKeyButtonsInView:(UIView *)view { + if (!view) { return @[]; } + NSMutableArray *buttons = [NSMutableArray array]; + [self kb_collectKeyButtonsInView:view into:buttons]; + return buttons.copy; +} + +- (void)kb_collectKeyButtonsInView:(UIView *)view + into:(NSMutableArray *)buttons { + for (UIView *sub in view.subviews) { + if ([sub isKindOfClass:[KBKeyButton class]]) { + [buttons addObject:(KBKeyButton *)sub]; + continue; + } + if (sub.subviews.count > 0) { + [self kb_collectKeyButtonsInView:sub into:buttons]; + } + } +} + #pragma mark - Key Model Construction // 创建当前布局下各行的 KBKey 列表