这对我来说有点头疼。在我正在构建的应用程序中,我正在使用UITextField,并添加一个按钮作为leftView属性。然而,似乎在iPad(包括SIM和设备)上,按钮正在接收超出其范围的触摸。当用户触摸占位符文本时,这会干扰UITextField成为第一个响应者的能力。似乎在触摸占位符文本时,事件由按钮而不是文本字段本身处理。奇怪的是,这似乎只发生在iPad上;它在iPhone上按预期工作。
以下是一些展示问题的简单代码:
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10.0f,
10.0f,
(self.view.frame.size.width - 20.0f),
35.0f)];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.placeholder = @"Test text";
[self.view addSubview:textField];
UIButton *addButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
[addButton addTarget:self action:@selector(touchDown:) forControlEvents:UIControlEventTouchDown];
[addButton addTarget:self action:@selector(touchUpInside) forControlEvents:UIControlEventTouchUpInside];
[addButton addTarget:self action:@selector(touchUpOutside) forControlEvents:UIControlEventTouchUpOutside];
textField.leftView = addButton;
textField.leftViewMode = UITextFieldViewModeAlways;
}
- (void)touchDown:(id)sender {
NSLog(@"touchDown");
}
- (void)touchUpInside {
NSLog(@"touchUpInside");
}
- (void)touchUpOutside {
NSLog(@"touchUpOutside");
}
似乎有时触摸仍然被认为是在内部,即使它们似乎在按钮的界限之外。然后再往前走,按钮只接收UIControlEventTouchDown然后接收UIControlEventTouchUpOutside。
2013-07-25 11:51:44.217 TestApp[22722:c07] touchDown
2013-07-25 11:51:44.306 TestApp[22722:c07] touchUpInside
2013-07-25 11:51:44.689 TestApp[22722:c07] touchDown
2013-07-25 11:51:44.801 TestApp[22722:c07] touchUpOutside
修改 下面是一个示例,其中按钮的背景颜色已更改,以及触发上述事件的大致区域。另外,我检查了按钮的框架,它的宽度小于30px。
答案 0 :(得分:4)
我坐了下来,在昨晚花了一些时间。我已经在我的实际应用程序中继承了UITextField,所以我最终覆盖了-(id)hitTest:withEvent:
,如下所示。到目前为止,这一直很好。
- (id)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if ([[super hitTest:point withEvent:event] isEqual:self.leftView]) {
if (CGRectContainsPoint(self.leftView.frame, point)) {
return self.leftView;
} else {
return self;
}
}
return [super hitTest:point withEvent:event];
}
答案 1 :(得分:1)
我验证了你的结果。我认为这很可能是UITextView
中的一个错误。不幸的是,出于某种原因,如果设置leftView
,该区域中的事件将被发送到错误的视图(在iPad上)。
我没有一个简单的解决方法,因为调整leftView的框架没有任何效果。我认为它需要修复到比我们可以访问的更低的水平。也许可以向Apple报告这个错误并暂时使用它?
你可以跟踪触摸的位置并忽略它,如果它超出范围,但对于一个小错误似乎很多工作?
答案 2 :(得分:1)
也遇到了这个问题,我发现其他一些解决方案是检查事件点是否位于按钮内。
- (void)touchUpInside:(UIButton *)sender event:(UIEvent *)event
{
CGPoint location = [[[event allTouches] anyObject] locationInView:sender];
if (!CGRectContainsPoint(sender.bounds, location)) {
// Outside of bounds, so ignore:
return;
}
// Inside our bounds, so continue as normal:
}