2013-07-25 4 views
2

Это для меня немного головной царапины. В приложении, которое я создаю, я использую UITextField и добавляю кнопку в качестве свойства leftView. Однако, похоже, что на iPad (как на симуле, так и на устройстве) кнопка получает штрихи, которые находятся за пределами ее границ. Это мешает способности UITextField стать первым ответчиком, когда пользователь коснется текста заполнителя. Кажется, что при касании текста заполнителя события обрабатываются кнопкой вместо самого текстового поля. Как ни странно, это похоже на iPad; он работает как ожидается на iPhone.UIButton получает события касания за пределами границ, когда установлено как leftView UITextField

Вот некоторые простой код, демонстрирующий проблему:

- (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 пикселей.

Example image

+0

изменить цвет фона кнопки и увидеть, что она заполняет в текстовом виде, а оттуда установить рамку, соответственно, если это не сработает, подкласс кнопки и использовать точку в методе боковой всех классов UIView и посмотрите, что он говорит, что позиции, если они нечетны, как отрицательные числа, затем возвращают NO из этой функции. Это не отвечает на ваш вопрос, но может помочь. –

+0

Попробуйте использовать buttonWithType Custom и установите рамку для кнопки; Таким образом, вы можете управлять размерами кнопок, независимо от того, хорошо ли кадр uibuttontypecontactadd. Есть вероятные разные кадры для этого типа кнопки для iPhone/iPad, поэтому различное поведение –

+0

Оцените предложения, но я проверил фрейм, и он, похоже, не соответствует. Это всего лишь около 30 пикселей. Я добавил скриншот выше, с измененным фоном цвета кнопки и приблизительными зонами, в которых эти события также запускаются.Я могу закончить маршрут подкласса либо UIButton, либо UITextField, чтобы попытаться исправить поведение, но хотел посмотреть, может быть, я вообще что-то пропустил. Интересно, это просто ошибка с UITextField. –

ответ

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

Я проверил свои результаты. Я думаю, что это скорее всего ошибка в UITextView. К сожалению, по какой-то причине, если вы установили leftView, события в этой области отправляются в неправильное представление (на iPad).

У меня нет простого обходного пути для вас, так как настройка рамки слева не влияет. Я думаю, что его нужно исправлять на более низком уровне, чем у нас есть. Может быть, сообщить об ошибке Apple и жить с ней на данный момент?

Вы можете отслеживать местоположение касания и игнорировать его, если это вне пределов, но, похоже, большая работа для незначительной ошибки?

+1

Спасибо - оцените подтверждение. Мне удалось довольно легко зафиксировать поведение, переопределив '- (id) hitTest: withEvent:', который я подробно описал в своем ответе ниже. –

+0

@KevinLord, круто. Спасибо, что опубликовали ваше решение. –

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: 
} 
Смежные вопросы