Подтвердить что ты не робот

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.

4b9b3361

Ответ 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 методами здесь. Работа будет зависеть от того, что вы хотите реализовать.