Почему hitTest: withEvent: вызывается три раза для каждого касания?
У меня есть подкласс UIView
, в котором я переопределил hitTest:withEvent:
следующим образом:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(@"Event = %@", event);
return self;
}
Для каждого касания в представлении я вижу три вызова hitTest:withEvent:
. Эти три вызова выполняются до касания. Выход выглядит следующим образом:
2011-07-01 09:20:58.553 AppName[930:207] Event = <UITouchesEvent: 0x6a08360> timestamp: 4297.16 touches: {(
)}
2011-07-01 09:20:58.553 AppName[930:207] Event = <UITouchesEvent: 0x6a08360> timestamp: 4297.16 touches: {(
)}
2011-07-01 09:20:58.554 AppName[930:207] Event = <UITouchesEvent: 0x6a08360> timestamp: 4304.54 touches: {(
)}
На основе временных меток и адресов появляется, как будто используется один объект UITouchesEvent
, а его временная метка неправильно настроена до третьего вызова. Может ли кто-нибудь объяснить, почему hitTest:withEvent:
вызывается три раза? Я не ищу обходного пути. Я просто хочу понять, что происходит.
Ответы
Ответ 1
У меня была такая же проблема, и я смог решить ее с помощью этого кода. Несмотря на то, что pointInside и hitTest вызываются 3 раза, touchBegan (или touchEnded) UIView, который был затронут, получает только один раз.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (event.type == UIEventTypeTouches)
NSLog(@"%@", self);
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if ([self pointInside:point withEvent:event])
return self;
return [super hitTest:point withEvent:event];
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (CGRectContainsPoint([self bounds], point))
{
if (event.type == UIEventTypeTouches)
{
return YES;
}
}
return NO;
}
Ответ 2
Есть ли у вас несколько подвью?
Из документов:
Этот метод перемещается по иерархии представлений, отправляя сообщение pointInside: withEvent: каждому подвью, чтобы определить, какой субвью должен получить событие касания. Если pointInside: withEvent: возвращает YES, то проходит иерархия subviews; в противном случае его ветвь иерархии представлений игнорируется. Вам редко нужно вызывать этот метод самостоятельно, но вы можете переопределить его, чтобы скрыть события касания от подзонов.
Ответ 3
Вы должны проверить, все ли свойства подтипа и типа. эти 3 события имеют смысл, поскольку там должно быть инициировано событие, чтобы ОС поняла природу события касания.
Например, проведите пальцем, зажмите и нажмите все, чтобы начать с того же события касания. Я предполагаю, что первые два уволены 1, чтобы зарегистрировать событие крана, а второе - для проверки события перехода на "перемещение". второй называется вскоре после этого, вероятно, либо отменить защемление/масштабирование/что угодно.
Внизу, в документах рассказывается о трех разных типах событий: о прикосновении, движении и удаленных событиях. Ссылка на класс UIEvent