Rolagem horizontal UIScrollView com gesto panorâmico vertical
-
12-12-2019 - |
Pergunta
Estou tentando implementar um UIScrollView em que a panorâmica horizontal rola pelas imagens no scrollview, mas a panorâmica vertical executa outra ação que tenho.No momento eu tenho um UIScrollView que é paginado com rolagem vertical desativada que funciona muito bem para rolar pelas imagens, mas estou enlouquecendo tentando encontrar uma maneira de interceptar movimentos verticais e chamar meu próprio método em vez dos movimentos verticais serem comidos por a visualização de rolagem.eu consegui fazer
UIPanGestureRecognizer *panUp = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
[self.scrollView addGestureRecognizer:panUp];
[scrollView.panGestureRecognizer setEnabled:NO];
O que me dá controle total sobre o movimento panorâmico no meu handlePanGesture:método, mas isso não é particularmente útil porque sinto que basicamente reescreverei toda a lógica de rolagem que estou tentando evitar.Qualquer ajuda ou orientação sobre como conseguir isso seria muito apreciada.
Obrigado!
Solução
Acho que isso será difícil se você quiser usar um gesto panorâmico por causa do uso desses gestos pela visualização de rolagem.No entanto, se você puder deslizar, é fácil de implementar.
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
swipe.direction = UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp;
[self.scrollView addGestureRecognizer:swipe];
Eu testei isso e funcionou bem para chamar o manipulador, e você não precisa desabilitar o reconhecedor de gesto panorâmico da visualização de rolagem (em meu teste, a visualização de rolagem era alta o suficiente e o conteúdo curto o suficiente para que não houvesse rolagem vertical - - Não sei se isso é necessário ou não).
Outras dicas
A partir do iOS 5, UIScrollView
expõe seu UIPanGestureRecognizer
.Defina seu deslizamento personalizado delegate
para self
e torne o gestoRecognizer uma propriedade ou ivar, e faça sua classe estar em conformidade com o <UIGestureRecognizerDelegate>
protocolo.Então, implemente UIGestureRecognizerDelegate
é – gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
igual a:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if ([gestureRecognizer isEqual:self.swipe] && [otherGestureRecognizer isEqual:self.scrollView.panGestureRecognizer])
{
return NO;
}
return YES; // the default for this method
}
Eu adicionei um UIPanGestureRecognizer
então configuregestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
assim:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([gestureRecognizer isEqual:self.panGesture] && [otherGestureRecognizer isEqual:self.collectionView.panGestureRecognizer]){
return YES;
}
return NO;
}
Eu também adicionei um check-in gestureRecognizerShouldBegin:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([gestureRecognizer isEqual:self.panGesture]) {
if (gestureRecognizer.numberOfTouches > 0) {
CGPoint point = [gestureRecognizer locationOfTouch:0 inView:gestureRecognizer.view];
CGFloat distX = abs(self.collectionView.lastTouchPos.x - point.x);
CGFloat distY = abs(self.collectionView.lastTouchPos.y - point.y);
if (distX > distY) {
return NO;
}
} else {
return NO;
}
}
return YES;
}
para usar apenas self.panGesture
ao deslocar para cima ou para baixo.
Atualizar
https://stackoverflow.com/a/8603839/667834 parece ter um método melhor para gestureRecognizerShouldBegin
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([gestureRecognizer isEqual:self.panGesture]) {
if (gestureRecognizer.numberOfTouches > 0) {
CGPoint translation = [self.panGesture velocityInView:self.collectionView];
return fabs(translation.y) > fabs(translation.x);
} else {
return NO;
}
}
return YES;
}