处理按钮之间点不到的问题 HitInside
This commit is contained in:
@@ -135,27 +135,42 @@ static const CGFloat kKBLettersRow2EdgeSpacerMultiplier = 0.5;
|
|||||||
if ([hit isKindOfClass:[KBKeyButton class]]) {
|
if ([hit isKindOfClass:[KBKeyButton class]]) {
|
||||||
return hit;
|
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];
|
KBKeyButton *btn = [self kb_nearestKeyButtonForPoint:point];
|
||||||
if (btn) { return btn; }
|
if (btn) { return btn; }
|
||||||
}
|
}
|
||||||
return hit;
|
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 {
|
- (KBKeyButton *)kb_nearestKeyButtonForPoint:(CGPoint)point {
|
||||||
// 扩大按键的可点击区域,优先响应间隙点击(贴近系统键盘手感)。
|
|
||||||
CGFloat slopX = KBFit(8.0f);
|
|
||||||
CGFloat slopY = KBFit(4.0f);
|
|
||||||
KBKeyButton *best = nil;
|
KBKeyButton *best = nil;
|
||||||
CGFloat bestDistance = CGFLOAT_MAX;
|
CGFloat bestDistance = CGFLOAT_MAX;
|
||||||
NSArray<UIView *> *rows = @[self.row1, self.row2, self.row3, self.row4];
|
NSArray<UIView *> *rows = @[self.row1, self.row2, self.row3, self.row4];
|
||||||
|
|
||||||
|
UIView *targetRow = nil;
|
||||||
for (UIView *row in rows) {
|
for (UIView *row in rows) {
|
||||||
for (UIView *view in row.subviews) {
|
CGRect rowFrame = [self convertRect:row.bounds fromView:row];
|
||||||
if (![view isKindOfClass:[KBKeyButton class]]) { continue; }
|
if (CGRectContainsPoint(rowFrame, point)) {
|
||||||
KBKeyButton *btn = (KBKeyButton *)view;
|
targetRow = row;
|
||||||
CGRect frame = [self convertRect:btn.frame fromView:row];
|
break;
|
||||||
CGRect hitFrame = CGRectInset(frame, -slopX, -slopY);
|
}
|
||||||
if (!CGRectContainsPoint(hitFrame, point)) { continue; }
|
}
|
||||||
|
|
||||||
|
NSArray<UIView *> *candidateRows = targetRow ? @[targetRow] : rows;
|
||||||
|
for (UIView *row in candidateRows) {
|
||||||
|
NSArray<KBKeyButton *> *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 dx = point.x - CGRectGetMidX(frame);
|
||||||
CGFloat dy = point.y - CGRectGetMidY(frame);
|
CGFloat dy = point.y - CGRectGetMidY(frame);
|
||||||
CGFloat dist = (dx * dx) + (dy * dy);
|
CGFloat dist = (dx * dx) + (dy * dy);
|
||||||
@@ -168,6 +183,26 @@ static const CGFloat kKBLettersRow2EdgeSpacerMultiplier = 0.5;
|
|||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSArray<KBKeyButton *> *)kb_collectKeyButtonsInView:(UIView *)view {
|
||||||
|
if (!view) { return @[]; }
|
||||||
|
NSMutableArray<KBKeyButton *> *buttons = [NSMutableArray array];
|
||||||
|
[self kb_collectKeyButtonsInView:view into:buttons];
|
||||||
|
return buttons.copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)kb_collectKeyButtonsInView:(UIView *)view
|
||||||
|
into:(NSMutableArray<KBKeyButton *> *)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
|
#pragma mark - Key Model Construction
|
||||||
|
|
||||||
// 创建当前布局下各行的 KBKey 列表
|
// 创建当前布局下各行的 KBKey 列表
|
||||||
|
|||||||
Reference in New Issue
Block a user