88 votes

Pagination horizontale UIScrollView comme les onglets Mobile Safari

Le navigateur Safari Mobile vous permet de basculer entre les pages par l'entrée d'une sorte de UIScrollView horizontale pagination de vue avec un contrôle de page en bas.

Je suis en train d'essayer de reproduire ce comportement particulier où un défilement horizontal UIScrollView montre une partie de la prochaine vue du contenu.

La Pomme de l'exemple fourni par: contrôle pagecontrol montre comment utiliser un UIScrollView horizontal de recherche, mais tous les points de vue de prendre toute la largeur de l'écran.

Comment puis-je obtenir un UIScrollView pour afficher le contenu de certains cours de la prochaine vue comme mobile de Safari?

265voto

Ed Marty Points 24861

Un UIScrollView avec la pagination est activée, s'arrêter à des multiples de sa largeur (ou la hauteur). Donc, la première étape est de comprendre comment la largeur que vous voulez que vos pages. Faire que la largeur de l' UIScrollView. Ensuite, définissez votre sous-vue de la taille mais grand vous en avez besoin pour être, et l'ensemble de leurs centres basée sur des multiples de l' UIScrollViews'de largeur.

Alors, puisque vous voulez voir les autres pages, bien sûr, clipsToBounds de NO comme mhjoy déclaré. Le truc maintenant la partie est de la faire défiler lorsque l'utilisateur démarre le glisser en dehors de la plage de l' UIScrollView'image. Ma solution (quand j'ai eu à faire cette très récemment) ont été comme suit:

Créer un UIView sous-classe (c - ClipView) qui contiendra l' UIScrollView et il est sous-vues. Essentiellement, il devrait avoir l'image de ce que l'on pourrait supposer l' UIScrollView auraient dans des conditions normales. Place de l' UIScrollView dans le centre de l' ClipView. Assurez-vous que l' ClipViews' clipsToBounds est définie à l' YES si sa largeur est inférieure à celle de son parent vue. Aussi, l' ClipView a besoin d'une référence à l' UIScrollView.

La dernière étape consiste à substituer - (UIView *)hitTest:withEvent: à l'intérieur de l' ClipView.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
  return [self pointInside:point withEvent:event] ? scrollView : nil;
}

En fait cela élargit la zone tactile de la UIScrollView à l'image de sa mère, exactement ce dont vous avez besoin.

Une autre option serait de la sous-classe UIScrollView et de remplacer son - (BOOL)pointInside:(CGPoint) point withEvent:(UIEvent *) event méthode, cependant, vous aurez toujours besoin d'un conteneur en vue de faire la coupure, et il peut être difficile de déterminer le moment du retour YES basé uniquement sur l' UIScrollView'image.

REMARQUE: Vous devez également prendre un coup d'oeil à la Juri Pakaste de hitTest:withEvent: modification si vous rencontrez des problèmes avec la sous-vue de l'utilisateur.

70voto

Juri Pakaste Points 762

La solution ClipView ci-dessus a fonctionné pour moi, mais je devais effectuer une implémentation différente de -[UIView hitTest:withEvent:] . La version d'Ed Marty n'a pas permis à l'utilisateur d'interagir avec les vues de défilement verticales que j'avais à l'intérieur de la vue horizontale.

La version suivante a fonctionné pour moi:

 -(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
    UIView* child = nil;
    if ((child = [super hitTest:point withEvent:event]) == self)
    	return self.scrollView;		
    return child;
}
 

5voto

djneely Points 105

J'ai fini par aller avec la coutume UIScrollView moi-même que c'était la plus rapide et la plus simple méthode, me semblait-il. Cependant, je ne vois pas de code exact donc pensé que je voudrais partager. Mes besoins pour un UIScrollView qui avait peu de contenu et, par conséquent, la UIScrollView elle-même était petite pour atteindre la pagination de l'affect. Comme le post-unis, vous ne pouvez pas balayer. Mais maintenant, vous le pouvez.

Créer une classe CustomScrollView et la sous-classe UIScrollView. Ensuite, tout ce que vous devez faire est d'ajouter ceci dans le .m fichier:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
  return (point.y >= 0 && point.y <= self.frame.size.height);
}

Cela vous permet de faire défiler de gauche à droite (horizontale). Ajuster les limites en conséquence à définir votre glisser/défilement de la zone tactile. Profitez-en!

4voto

alvinhu Points 56

J'ai fait une autre implémentation qui peut renvoyer le scrollview automatiquement. Il n'est donc pas nécessaire d'avoir un IBOutlet qui limitera la réutilisation dans le projet.

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if ([self pointInside:point withEvent:event]) {
        for (id view in [self subviews]) {
            if ([view isKindOfClass:[UIScrollView class]]) {
                return view;
            }
        }
    }
    return nil;
}
 

3voto

Rod Reddekopp Points 51

J'ai une autre modification potentiellement utile pour l'implémentation ClipView hitTest. Je n'aimais pas avoir à fournir une référence UIScrollView à ClipView. Mon implémentation ci-dessous vous permet de réutiliser la classe ClipView pour élargir la zone de test d'accès, sans avoir à lui fournir de référence.

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (([self pointInside:point withEvent:event]) && (self.subviews.count >= 1))
    {
        // An extended-hit view should only have one sub-view, or make sure the
        // first subview is the one you want to expand the hit test for.
        return [self.subviews objectAtIndex:0];
    }

    return nil;
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X