web-dev-qa-db-fra.com

Sensibilité / Vitesse de défilement de UIScrollView avec pagination

Je veux que UIScrollView défile rapidement après un balayage rapide, comme ceci . Bien que lorsque la pagination est activée, le défilement fonctionne ne page à la fois . Est-il possible de faire défiler rapidement, lorsque la pagination est activée d'un simple coup de doigt sans implémentation manuelle à l'aide de reconnaissance de gestes?

27
UrK

C'est assez simple, mais vous devez implémenter vous-même l'aspect de la pagination (ce qui est assez simple). Vous n'avez pas besoin de reconnaissance de gestes.

Swift

Tout d'abord, ajustez votre IScrollView taux de décélération:

scrollView.decelerationRate = UIScrollViewDecelerationRateFast

Supposons que nous ayons un tableau de contenu - appelons-le yourPagesArray. Dans votre IScrollViewDelegate, implémentez la méthode suivante:

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
{
    //This is the index of the "page" that we will be landing at
    let nearestIndex = Int(CGFloat(targetContentOffset.pointee.x) / scrollView.bounds.size.width + 0.5)

    //Just to make sure we don't scroll past your content
    let clampedIndex = max( min( nearestIndex, yourPagesArray.count - 1 ), 0 )

    //This is the actual x position in the scroll view
    var xOffset = CGFloat(clampedIndex) * scrollView.bounds.size.width

    //I've found that scroll views will "stick" unless this is done
    xOffset = xOffset == 0.0 ? 1.0 : xOffset

    //Tell the scroll view to land on our page
    targetContentOffset.pointee.x = xOffset
}

Vous devrez également implémenter la méthode déléguée suivante, pour gérer le cas où l'utilisateur lève doucement le doigt sans provoquer de décélération du défilement:

(Mise à jour: vous n'aurez peut-être pas besoin de le faire sous le dernier SDK iOS. Il semble que la méthode déléguée ci-dessus soit maintenant appelée lorsqu'il n'y a aucune vélocité.)

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
{
    if !decelerate
    {
        let currentIndex = floor(scrollView.contentOffset.x / scrollView.bounds.size.width)

        let offset = CGPoint(x: scrollView.bounds.size.width * currentIndex, y: 0)

        scrollView.setContentOffset(offset, animated: true)
    }
}

Objectif c

Réglage de votre taux de décélération:

scrollView.decelerationRate = UIScrollViewDecelerationRateFast;

Ensuite, votre implémentation de délégué de vue de défilement:

- (void) scrollViewWillEndDragging:(UIScrollView *)scroll withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
    //This is the index of the "page" that we will be landing at
    NSUInteger nearestIndex = (NSUInteger)(targetContentOffset->x / scrollView.bounds.size.width + 0.5f);   

    //Just to make sure we don't scroll past your content
    nearestIndex = MAX( MIN( nearestIndex, yourPagesArray.count - 1 ), 0 );

    //This is the actual x position in the scroll view
    CGFloat xOffset = nearestIndex * scrollView.bounds.size.width;

    //I've found that scroll views will "stick" unless this is done
    xOffset = xOffset==0?1:xOffset;

    //Tell the scroll view to land on our page
    *targetContentOffset = CGPointMake(xOffset, targetContentOffset->y);
}

- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if( !decelerate )
    {
        NSUInteger currentIndex = (NSUInteger)(scrollView.contentOffset.x / scrollView.bounds.size.width);

        [scrollView setContentOffset:CGPointMake(scrollView.bounds.size.width * currentIndex, 0) animated:YES];
    }
}
51
simeon

Je pense que nous pouvons définir scrollView.userInteractionEnabled = NO lorsque notre doigt le touche. Et puis lorsque l'animation est arrêtée, ouvrez-la. Cela fonctionne pour moi. J'espère que cela vous aidera.

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    scrollView.userInteractionEnabled = NO;
}

// at the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    scrollView.userInteractionEnabled = YES;
}
1
Hilen