UIScrollViewDelegate tem dois métodos de delegado scrollViewDidScroll:
e scrollViewDidEndScrollingAnimation:
, mas nenhum destes dizer quando rolagem foi concluída. scrollViewDidScroll
notifica apenas que a exibição de rolagem rolou e não que terminou a rolagem.
O outro método scrollViewDidEndScrollingAnimation
só parece acionar se você mover programaticamente a exibição de rolagem e não se o usuário rolar.
Alguém sabe de esquema para detectar quando uma exibição de rolagem concluiu a rolagem?
ios
iphone
uiscrollview
Michael Gaylord
fonte
fonte
Respostas:
fonte
As 320 implementações são muito melhores - aqui está um patch para obter início / fim consistentes do pergaminho.
fonte
Acho scrollViewDidEndDecelerating é o que você deseja. Seu método opcional UIScrollViewDelegates:
Informa ao delegado que a exibição de rolagem terminou a desaceleração do movimento de rolagem.
Documentação do UIScrollViewDelegate
fonte
Para todos os pergaminhos relacionados às interações de arrastar, isso será suficiente:
Agora, se o seu scroll for devido a um setContentOffset / scrollRectVisible programático (com
animated
= YES ou você obviamente sabe quando o scroll termina):Se o seu deslocamento for devido a outra coisa (como abertura ou fechamento do teclado), parece que você terá que detectar o evento com um hack, porque
scrollViewDidEndScrollingAnimation
também não é útil.O caso de uma exibição de rolagem PAGINATED :
Porque, eu acho, a Apple aplica uma curva de aceleração,
scrollViewDidEndDecelerating
é chamada para cada arrastar, então não há necessidade de usarscrollViewDidEndDragging
neste caso.fonte
scrollViewDidEndDecelerating
não será chamado #Isso foi descrito em algumas das outras respostas, mas aqui está (no código) como combinar
scrollViewDidEndDecelerating
escrollViewDidEndDragging:willDecelerate
executar alguma operação quando a rolagem terminar:fonte
Acabei de encontrar esta pergunta, que é praticamente a mesma que perguntei: Como saber exatamente quando a rolagem de um UIScrollView parou?
Embora didEndDecelerating funcione ao rolar, o movimento panorâmico com liberação estacionária não é registrado.
Acabei encontrando uma solução. didEndDragging possui um parâmetro WillDecelerate, que é falso na situação de liberação estacionária.
Ao verificar! Desacelerar em DidEndDragging, combinado com didEndDecelerating, você obtém as duas situações que são o fim da rolagem.
fonte
Se você gosta de Rx, pode estender o UIScrollView assim:
o que permitirá que você faça assim:
Isso levará em consideração o arraste e a desaceleração.
fonte
fonte
Eu tentei a resposta de Ashley Smart e funcionou como um encanto. Aqui está outra idéia: usar apenas scrollViewDidScroll
Eu só tinha duas páginas, então funcionou para mim. No entanto, se você tiver mais de uma página, isso poderá ser problemático (você poderá verificar se o deslocamento atual é múltiplo da largura, mas não saberá se o usuário parou na 2ª página ou se está na terceira ou na terceira página. Mais)
fonte
Versão rápida da resposta aceita:
fonte
Se alguém precisar, aqui está a resposta Ashley Smart em Swift
fonte
Solução recém-desenvolvida para detectar quando a rolagem terminou em todo o aplicativo: https://gist.github.com/k06a/731654e3168277fb1fd0e64abc7d899e
Baseia-se na ideia de rastrear alterações nos modos runloop. E execute blocos pelo menos após 0,2 segundos após a rolagem.
Esta é a ideia principal para acompanhar os modos de execução em execução iOS10 +:
E solução para destinos de baixa implantação como o iOS2 +:
fonte
Para recapitular (e para iniciantes). Não é tão doloroso. Basta adicionar o protocolo e, em seguida, adicionar as funções necessárias para a detecção.
Na visualização (classe) que contém o UIScrolView, adicione o protocolo e, em seguida, adicione quaisquer funções daqui à sua visualização (classe).
fonte
Tive um caso de ações de tocar e arrastar e descobri que o arrasto chamava scrollViewDidEndDecelerating
E a alteração deslocada manualmente com o código ([_scrollView setContentOffset: contentOffset animated: YES];) estava chamando scrollViewDidEndScrollingAnimation.
fonte
Uma alternativa seria usar a
scrollViewWillEndDragging:withVelocity:targetContentOffset
chamada sempre que o usuário levantar o dedo e contiver o deslocamento do conteúdo de destino onde a rolagem será interrompida. O uso desse deslocamento de conteúdoscrollViewDidScroll:
identifica corretamente quando a exibição de rolagem parou de rolar.fonte
O UIScrollview possui um método delegado
Adicione as linhas de código abaixo no método delegado
fonte
Existe um método
UIScrollViewDelegate
que pode ser usado para detectar (ou melhor, dizer 'prever') quando a rolagem realmente terminou:dos
UIScrollViewDelegate
quais podem ser usados para detectar (ou melhor, dizer 'prever') quando a rolagem realmente terminou.No meu caso, usei-o com rolagem horizontal da seguinte forma (no Swift 3 ):
fonte
Usando a lógica Ashley Smart e está sendo convertido no Swift 4.0 e superior.
A lógica acima resolve problemas como quando o usuário está rolando para fora da tableview. Sem a lógica, quando você rolar a tela,
didEnd
será chamado, mas não executará nada. Atualmente usando-o no ano 2020.fonte
Em algumas versões anteriores do iOS (como iOS 9, 10),
scrollViewDidEndDecelerating
não será acionado se o scrollView for subitamente interrompido ao tocar.Mas na versão atual (iOS 13),
scrollViewDidEndDecelerating
será acionado com certeza (tanto quanto eu sei).Portanto, se o seu aplicativo também segmentou versões anteriores, você pode precisar de uma solução alternativa, como a mencionada por Ashley Smart, ou a seguinte.
Explicação
O UIScrollView será parado de três maneiras:
- rolou e parou
rapidamente sozinho - rolou e parou rapidamente com o toque do dedo (como freio de emergência)
- rolou e parou lentamente
O primeiro pode ser detectado por
scrollViewDidEndDecelerating
e outros métodos similares, enquanto os outros dois não.Felizmente,
UIScrollView
possui três status que podemos usar para identificá-los, que é usado nas duas linhas comentadas por "// 1" e "// 2".fonte