3

这对我来说有点头疼。在我正在构建的应用程序中,我正在使用 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

编辑 这是一个更改按钮背景颜色以及触发上述事件的近似区域的示例。另外,我检查了按钮的框架,它的宽度小于 30 像素。

示例图片

4

3 回答 3

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];
}
于 2013-07-26T16:12:34.050 回答
1

我验证了你的结果。我认为这很可能是UITextView. 不幸的是,由于某种原因,如果您设置leftView,该区域中的事件将被发送到错误的视图(在 iPad 上)。

我没有一个简单的解决方法,因为调整 leftView 的框架没有效果。我认为它需要固定在比我们能够访问的更低的水平。也许将错误报告给Apple并暂时忍受它?

您可以跟踪触摸的位置并在超出范围时忽略它,但是对于一个小错误来说似乎需要做很多工作?

于 2013-07-25T18:41:25.997 回答
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:
}
于 2015-11-08T16:23:22.273 回答