Поведение касания UIView изменилось с Xcode 4.2?

Пару дней назад я обновил свой iPad до версии 5.0 и одновременно обновил Xcode до версии 4.2, чтобы продолжить тестирование своих приложений. Теперь у меня проблемы с сенсорным кодом в нескольких приложениях, которые работали с предыдущими версиями Xcode.

Я создал подкласс UIImageView, чтобы добавить некоторые функции перетаскивания, переопределив -(void)TouchesBegan и -(void)TouchesMoved. Я не переопределил -(void)TouchesEnded в подклассе, но обработал это в контроллере представления для представления, содержащего представление изображения.

Я включил подкласс UIImageView в новый проект для тестирования и сузил проблему до того факта, что родительский UIView (шаблон, созданный Xcode), похоже, не перенаправляет события касания в контроллер представления (также созданный Xcode).

Если я добавлю это в свой подкласс:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches ended event in ImageToDrag");
    [self.nextResponder touchesEnded:touches withEvent:event];
}

и это для контроллера представления моего родительского представления:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches ended event in ViewController");
}

когда я отпускаю изображение, которое я перетаскиваю по экрану, я получаю "touches ended event in ImageToDrag", но не журнал из контроллера представления.

Однако, если я намеренно пропущу представление, сделав это в представлении подкласса:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches ended event in ImageToDrag");
    [[self.nextResponder nextResponder] touchesEnded:touches withEvent:event];
}

то я получаю обе записи журнала.

Единственное объяснение, которое я могу придумать, это то, что по какой-то причине UIView потребляет событие touchesEnded и не передает его контроллеру представления.

Я проверил, что exclusiveTouch установлено на NO, а userInteractionEnabled установлено на YES в родительском представлении и подклассе UIImageView.

Я также протестировал компиляцию для iOS 5.0 и iOS 4.2 и развертывание тестового приложения как на iPad с iOS 5, так и на iPad с iOS 4.3.1.

Единственный способ, которым я смог получить событие касания для viewController, - это пропустить представление и использовать двойное nextResponder в подклассе. Хотя этот метод работает, он кажется мне взломом, и я уверен, что он аукнется позже.

Кто-нибудь еще видел такое поведение? Есть ли способ узнать, что UIView делает с моими сенсорными событиями?

Спасибо, Дэн


person dlenhard    schedule 16.10.2011    source источник


Ответы (2)


Я пытался отследить аналогичную проблему в течение последних нескольких часов. Наконец удалось решить эту проблему с помощью этот пост

На самом деле похоже, что мне только что удалось решить эту проблему, используя подсказку с https://devforums.apple.com/message/519690#519690
Раньше я просто перенаправлял событие touchesEnded на self.nextResponder. Когда я добавил обработчики touchesBegan, Moved, Canceled с реализацией, аналогичной touchesEnded, событие, кажется, всплывает в корневом контроллере представления.

Мне не нужно было добавлять Moved/и т. д., я просто переслал на TouchesBegan, а затем TouchesEnded снова начал работать!

person Danny Tuppeny    schedule 19.10.2011
comment
Это помогло. Суть заключалась в том, что мне приходилось пересылать свои события в супервизор после их обработки. Еще одно замечание: мне пришлось использовать super вместо self.nextResponder, чтобы заставить его работать. - person dlenhard; 20.10.2011
comment
Спасибо за этот ответ. Рвал на себе волосы на этом. - person Steven Baughman; 17.02.2012

В iOS 5.0 произошла некоторая обработка касаний; особенно если вы повторно свяжете свое приложение с SDK 5.0.

В разделе «Методы обработки касания UIView» говорится следующее:

Если вы переопределяете этот метод, не вызывая super (распространенный шаблон использования), вы также должны переопределить другие методы для обработки событий касания, хотя бы в виде заглушек (пустых) реализаций.

Так что, если вы делаете один, вам нужно сделать их все. Я знаю, что UIKit начал предпринимать шаги, чтобы убедиться, что это так в версии 5.0.

Итак, я бы начал с этого - переопределите все методы в вашем представлении и посмотрите, что произойдет.

person Chris Parker    schedule 17.10.2011
comment
Я переопределяю touchesBegan и touchesMoved в подклассе... но не touchesCancelled. Я попробую это, чтобы увидеть, проясняется ли это. - person dlenhard; 17.10.2011
comment
Я также попытался переопределить touchesCancelled в представлении, и он по-прежнему не работает без использования двойного nextResponder. - person dlenhard; 17.10.2011