UIScrollView предотвращает прикосновения - PullRequest
26 голосов
/ 16 сентября 2011

Я обрабатываю касания для пары моих компонентов пользовательского интерфейса в моем контроллере представления (пользовательский подкласс UIViewController).У него есть методы touchesBegan:withEvent:, touchesMoved:withEvent: и touchesEnded:withEvent:.Работало нормально.Затем я добавил представление прокрутки (UIScrollView) как вид сверху в иерархии.

Теперь мои сенсорные обработчики на контроллере представления не работают.Им не звонят.Интересно то, что у меня есть несколько других компонентов пользовательского интерфейса в представлении прокрутки, которые работают.Некоторые из них являются кнопками, некоторые являются пользовательскими представлениями, которые определяют их собственные touchesBegan:withEvent: и т. Д. Единственное, что не работает, - это сенсорные обработчики на контроллере представления.

Я подумал, что это может быть из-за того, что представление с прокруткойперехватывая эти прикосновения для своих собственных целей, но я подклассифицировал UIScrollView и просто чтобы посмотреть, смогу ли я заставить его работать, я возвращаю YES всегда из touchesShouldBegin:withEvent:inContentView: и NO всегда из touchesShouldCancelInContentView:.Все еще не работает.

Если это имеет значение, мой контроллер представления находится в контроллере панели вкладок, но я не думаю, что это актуально.

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

Ответы [ 5 ]

22 голосов
/ 30 января 2012

создайте подкласс класса UIScrollView и переопределите touchesBegan: и другие сенсорные методы следующим образом:

-(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 голосов
/ 16 сентября 2011

Ну, это сработало, но я не уверен, что смогу "сойти с рук", поскольку 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

Затем в Интерфейсном Разработчике я сделал прямое подпредставление представления прокрутки одним из них и подключил его newNextResponder, чтобы пропустить представление прокрутки и указать непосредственно на контроллер представления.

Это также работает, заменяя переопределениеnextResponder с этими переопределениями:

- (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];
}
0 голосов
/ 24 января 2016

Пользователь user1085093 сработал для меня.Однако после того, как вы переместили касание более чем на небольшое количество, оно будет интерпретировано как «Жест панорамирования».

Я преодолел это, изменив поведение распознавателя «Жест панорамирования», поэтому для него требуется два пальца:1004 *

0 голосов
/ 16 сентября 2011

Методы touchesBegan: etc будут НИКОГДА не вызываться в UIScrollView, поскольку это подкласс UIView и переопределяет эти методы. проверить различные UIScrollView методы доступны здесь . Обходной путь будет зависеть от того, что вы хотите реализовать.

0 голосов
/ 16 сентября 2011

"Это работало нормально. Затем я добавил представление прокрутки (UIScrollView) в качестве вида сверху в иерархии."

Является ли ваше представление прокрутки поверх просмотра содержимого, которое содержит элементы?

все ваши компоненты должны быть в просмотре прокрутки, а не в представлении позади просмотра прокрутки

...