web-dev-qa-db-fra.com

UIScrollView, atteignant le bas de la vue de défilement

Je sais que la documentation Apple utilise la méthode de délégation suivante:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;      // called when scroll view grinds to a halt

Cependant, cela ne signifie pas nécessairement que vous êtes au bas. Parce que si vous utilisez votre doigt, faites défiler un peu, puis il décélère, mais vous n'êtes pas réellement au bas de votre vue de défilement, il est toujours appelé. En gros, je veux une flèche qui montre qu'il y a plus de données dans ma vue de défilement, puis qui disparaît lorsque vous êtes au bas (comme quand elle rebondit). Merci.

34
Crystal

Je pense que ce que vous pourriez être capable de faire est de vérifier que votre point contentOffset est au bas de contentSize. Donc, vous pourriez probablement faire quelque chose comme:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
    if (bottomEdge >= scrollView.contentSize.height) {
        // we are at the end
    }
}

Vous aurez probablement aussi besoin d'un cas négatif pour afficher votre indicateur lorsque l'utilisateur fait défiler vers le haut. Vous voudrez peut-être également ajouter un peu de remplissage à celui-ci, par exemple, vous pourriez masquer l'indicateur lorsque l'utilisateur est près du bas, mais pas exactement au bas.

97
bensnider

Donc, si vous le voulez dans Swift, voici: 

override func scrollViewDidScroll(scrollView: UIScrollView) {

    if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) {
        //reach bottom
    }

    if (scrollView.contentOffset.y < 0){
        //reach top
    }

    if (scrollView.contentOffset.y >= 0 && scrollView.contentOffset.y < (scrollView.contentSize.height - scrollView.frame.size.height)){
        //not top and not bottom
    }
}
16
ytbryan

Je pense que @bensnider répond est correcte, mais pas exart. Pour ces deux raisons

1. - (void)scrollViewDidScroll:(UIScrollView *)scrollView{}

Cette méthode appellera continuellement si nous vérifions if (bottomEdge >= scrollView.contentSize.height) 

2 Dans ce cas, si nous optons pour ==, cette condition sera également valide deux fois.

  • (i) quand nous allons défiler vers le haut lorsque la fin de la vue défilement touche le bord inférieur 
  • (ii) Lorsque la vue défilante rebondit pour conserver sa propre position

Je pense que c'est plus précis.

Très peu de cas cette codition est valable deux fois également. Mais l'utilisateur ne rencontrera pas cela.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
 {
    if (scrollView.contentOffset.y == roundf(scrollView.contentSize.height-scrollView.frame.size.height)) {
    NSLog(@"we are at the endddd");

   //Call your function here...

    }
}
14
umakanta

La réponse acceptée ne fonctionne que si la valeur contentInset inférieure est non négative. Une légère évolution considérerait le bas de la contentInset quel que soit son signe:

CGFloat bottomInset = scrollView.contentInset.bottom;
CGFloat bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height - bottomInset;
if (bottomEdge == scrollView.contentSize.height) {
    // Scroll view is scrolled to bottom
}
9
kadam

En fait, plutôt que de simplement mettre le code de @ bensnider dans scrollViewDidScroll, ce code (écrit en Swift 3) serait plus performant:

func scrollViewDidEndDragging(_ scrollView: UIScrollView,
                              willDecelerate decelerate: Bool) {
    if !decelerate {
        checkHasScrolledToBottom()
    }
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    checkHasScrolledToBottom()
}

func checkHasScrolledToBottom() {
    let bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height
    if bottomEdge >= scrollView.contentSize.height {
        // we are at the end
    }
}
3
Ivan

Cela fonctionne dans Swift 3:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if scrollView.contentOffset.y == (scrollView.contentSize.height - scrollView.frame.size.height) {
        loadMore()
    }
}
2
Zhanserik

Voir quels éléments sont actuellement affichés dans UIView, en utilisant quelque chose comme indexPathsForVisibleRows et si votre modèle a plus d’articles qu’il n’est affiché, placez une flèche en bas.

0
Abizern