Faire défiler un UIScrollView par programme


159

J'ai un UIScrollViewqui a plusieurs vues. Lorsqu'un utilisateur effleure son doigt, la vue défile vers la droite ou la gauche selon la direction de l'effleurement du doigt. Fondamentalement, mon code fonctionne de manière similaire à l'application photo iPhone. Maintenant, y a-t-il un moyen pour que je puisse faire la même chose par programmation pour que je me retrouve avec un diaporama qui s'exécute seul avec un clic sur un bouton et une pause configurable entre chaque défilement?

Comment faites-vous vraiment des diaporamas UIScrollView?

Réponses:


391

Vous pouvez faire défiler jusqu'à un certain point dans une vue de défilement avec l'une des instructions suivantes dans Objective-C

[scrollView setContentOffset:CGPointMake(x, y) animated:YES];

ou Swift

scrollView.setContentOffset(CGPoint(x: x, y: y), animated: true)

Consultez également le guide « Faire défiler le contenu de la vue par défilement » d'Apple .

Pour faire des diaporamas avec UIScrollView, vous organisez toutes les images dans la vue de défilement, configurez une minuterie répétée, puis -setContentOffset:animated:lorsque la minuterie se déclenche.

Mais une approche plus efficace consiste à utiliser 2 vues d'image et à les échanger en utilisant des transitions ou simplement en changeant de place lorsque la minuterie se déclenche. Voir Diaporama d'images iPhone pour plus de détails.


1
Cool. Oui, j'ai trouvé que setContentOffset fonctionne mais je voulais vraiment que cela se produise de manière animée. «animé: OUI» a fait l'affaire.
climbon le

3
Complétant simplement la réponse, pour passer horizontalement à la "page" suivante dans UIScrollView (en supposant que vous codez pour iPhone), pour l'utilisation du paramètre x (myScrollView.contentOffset.x +320).
Giovanni

2
@niraj merci mec ... en (myScrollView.contentOffset.x +320)réside la clé!
D_D

5
Corrigez-moi si je me trompe, mais UIScrollView contentOffset:compensera également le contentSize, ce qui peut ne pas être souhaitable. Pour faire défiler uniquement, vous pouvez utiliser scrollRectToVisible:.
Chris

N'utilisez pas les fonctions d'assistance C comme CGPointMakedans Swift. Créez simplement une structure Swift directement:CGPoint(x: 0, y: 44)
Arnold

42

Si vous souhaitez contrôler la durée et le style de l'animation, vous pouvez faire:

[UIView animateWithDuration:2.0f delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
    scrollView.contentOffset = CGPointMake(x, y);
} completion:NULL];

Ajustez la durée ( 2.0f) et les options ( UIViewAnimationOptionCurveLinear) au goût!


11

Une autre façon est

scrollView.contentOffset = CGPointMake(x,y);

14
C'est exactement la même chose que la réponse acceptée. Et CGPointdevrait l'être CGPointMake.
Evan Mulawski

J'aime les réponses simples comme celle-ci.
quemeful

En fait, ce n'est pas la même chose que la réponse acceptée. La réponse acceptée a une option d'animation, que certaines applications peuvent souhaiter définir sur OUI.
Rickster

11

Avec animation dans Swift

scrollView.setContentOffset(CGPointMake(x, y), animated: true)

6

Je suis étonné que ce sujet ait 9 ans et que la réponse directe ne soit pas ici!

Ce que vous recherchez, c'est scrollRectToVisible(_:animated:).

Exemple:

extension SignUpView: UITextFieldDelegate {
    func textFieldDidBeginEditing(_ textField: UITextField) {
        scrollView.scrollRectToVisible(textField.frame, animated: true)
    }
}

Ce qu'il fait est exactement ce dont vous avez besoin, et c'est bien meilleur que le piratage contentOffset

Cette méthode fait défiler la vue de contenu de sorte que la zone définie par rect soit juste visible à l'intérieur de la vue de défilement. Si la zone est déjà visible, la méthode ne fait rien.

De: https://developer.apple.com/documentation/uikit/uiscrollview/1619439-scrollrecttovisible


3
scrollView.setContentOffset(CGPoint(x: y, y: x), animated: true)

3

Swift 3

   let point = CGPoint(x: 0, y: 200) // 200 or any value you like.
    scrollView.contentOffset = point


0
- (void)viewDidLoad
{
    [super viewDidLoad];
    board=[[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.height, 80)];
    board.backgroundColor=[UIColor greenColor];
    [self.view addSubview:board];
    // Do any additional setup after loading the view.
}


-(void)viewDidLayoutSubviews
{


    NSString *str=@"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    index=1;
    for (int i=0; i<20; i++)
    {
        UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(-50, 15, 50, 50)];
        lbl.tag=i+1;
        lbl.text=[NSString stringWithFormat:@"%c",[str characterAtIndex:arc4random()%str.length]];
        lbl.textColor=[UIColor darkGrayColor];
        lbl.textAlignment=NSTextAlignmentCenter;
        lbl.font=[UIFont systemFontOfSize:40];
        lbl.layer.borderWidth=1;
        lbl.layer.borderColor=[UIColor blackColor].CGColor;
        [board addSubview:lbl];
    }

    [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(CallAnimation) userInfo:nil repeats:YES];

    NSLog(@"%d",[board subviews].count);
}


-(void)CallAnimation
{

    if (index>20) {
        index=1;
    }
    UIView *aView=[board viewWithTag:index];
    [self doAnimation:aView];
    index++;
    NSLog(@"%d",index);
}

-(void)doAnimation:(UIView*)aView
{
    [UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveLinear  animations:^{
        aView.frame=CGRectMake(self.view.frame.size.height, 15, 50, 50);
    }
                     completion:^(BOOL isDone)
     {
         if (isDone) {
             //do Somthing
                        aView.frame=CGRectMake(-50, 15, 50, 50);
         }
     }];
}

8
Veuillez envisager d'ajouter du texte à votre réponse, pas seulement du code pur
user1781290
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.