UIScrollView предотвращает прикосновенияBegan, касается touchMoved, touchhesEnded on view controller
Я обрабатываю штрихи для нескольких компонентов моего интерфейса в контроллере представления (пользовательский подкласс UIViewController). Он имеет методы touchesBegan:withEvent:
, touchesMoved:withEvent:
и touchesEnded:withEvent:
. Он работал нормально. Затем я добавил представление прокрутки (UIScrollView) в качестве верхнего вида в иерархии.
Теперь мои обработчики касаний на контроллере представления не работают. Их не называют. Интересно то, что у меня есть различные другие компоненты пользовательского интерфейса в прокрутке, которые работают. Некоторые из них являются кнопками, некоторые из них представляют собой пользовательские представления, которые определяют их собственные touchesBegan:withEvent:
и т.д. Единственное, что не работает, - это обработчики сенсорных элементов на контроллере представления.
Я подумал, может быть, потому, что представление прокрутки перехватывает эти штрихи в своих целях, но я подклассифицировал UIScrollView и просто посмотрел, могу ли я заставить его работать. Я возвращаю YES
всегда из touchesShouldBegin:withEvent:inContentView:
и NO
всегда от touchesShouldCancelInContentView:
. Все еще не работает.
Если это имеет значение, мой контроллер представления находится внутри контроллера панели вкладок, но я не думаю, что он имеет значение.
У кого-нибудь была эта проблема и есть готовое решение? Я предполагаю, что обезьяны прокрутки просматривают цепочку ответчиков. Могу ли я обезвредить его? Я предполагаю, что если я не могу понять ничего другого, я сделаю вид верхнего уровня под моим представлением прокрутки, являющимся настраиваемым представлением и пересылающим сообщения на контроллер вида, но кажется kludgy.
Ответы
Ответ 1
создайте подкласс класса UIScrollView и переопределите touchtsBegan: и другие методы касания следующим образом:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// If not dragging, send event to next responder
if (!self.dragging){
[self.nextResponder touchesBegan: touches withEvent:event];
}
else{
[super touchesBegan: touches withEvent: event];
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
// If not dragging, send event to next responder
if (!self.dragging){
[self.nextResponder touchesMoved: touches withEvent:event];
}
else{
[super touchesMoved: touches withEvent: event];
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
// If not dragging, send event to next responder
if (!self.dragging){
[self.nextResponder touchesEnded: touches withEvent:event];
}
else{
[super touchesEnded: touches withEvent: event];
}
}
Ответ 2
Ну, это сработало, но я не уверен, что смогу "сбежать от него", поскольку nextResponder не является одним из методов UIView, которые вам "рекомендуется" переопределять в подклассе.
@interface ResponderRedirectingView : UIView {
IBOutlet UIResponder *newNextResponder;
}
@property (nonatomic, assign) IBOutlet UIResponder *newNextResponder;
@end
@implementation ResponderRedirectingView
@synthesize newNextResponder;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (UIResponder *)nextResponder {
return self.newNextResponder;
}
- (void)dealloc
{
[super dealloc];
}
@end
Затем в Interface Builder я сделал прямое под просмотр прокрутки одним из них и подключил его newNextResponder, чтобы пропустить прокрутку и указать непосредственно на контроллер вида.
Это тоже работает, заменяя переопределение следующегоResponder этими переопределениями:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.newNextResponder touchesBegan:touches withEvent:event];
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self.newNextResponder touchesMoved:touches withEvent:event];
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.newNextResponder touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self.newNextResponder touchesCancelled:touches withEvent:event];
}
Ответ 3
"Он работал нормально. Затем я добавил в список вид сверху (UIScrollView) как верхний вид в иерархии.
- это ваш scrollview поверх вашего содержимого, содержащего элементы?
все ваши компоненты должны находиться в scrollview, а не в представлении scrollview
Ответ 4
user1085093 Ответ работал у меня. Однако, если вы перемещаете прикосновение более чем на небольшую величину, оно затем интерпретируется как "Жест".
Я преодолел это, изменив поведение распознавателя Pan Gesture, поэтому он требует двух пальцев:
-(void)awakeFromNib
{
NSArray *gestureRecognizers = self.gestureRecognizers;
UIGestureRecognizer *gestureRecognizer;
for (gestureRecognizer in gestureRecognizers) {
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
UIPanGestureRecognizer *pgRecognizer = (UIPanGestureRecognizer*)gestureRecognizer;
pgRecognizer.minimumNumberOfTouches = 2;
}
}
}
Ответ 5
touchesBegan:
и т.д. методы будут НИКОГДА вызывать в UIScrollView
, потому что это подкласс UIView
и переопределяет эти методы. ознакомьтесь с различными UIScrollView
методами здесь. Работа будет зависеть от того, что вы хотите реализовать.