77 votes

Puis-je utiliser un UIRefreshControl dans un UIScrollView?

J'ai environ 5 UIScrollView's déjà dans mon application qui tous de charger de multiples .xib fichiers. Nous voulons maintenant utiliser un UIRefreshControl. Ils sont conçus pour être utilisés avec UITableViewControllers (par UIRefreshControl classe de référence). Je ne veux pas re-faire comment toutes les 5 UIScrollView de travail. J'ai déjà essayé d'utiliser l' UIRefreshControl mon UIScrollViews', et il fonctionne comme prévu, sauf pour quelques choses.

  1. Juste après l'actualisation de l'image se transforme en chargeur, l' UIScrollView sauts en baisse d'environ 10 pixels, qui ne n'arrive pas quand je suis très prudent pour faire glisser l' UIScrollview très lentement.

  2. Quand je scroll vers le bas et de lancer la recharge, puis laissez-le aller de l' UIScrollView, UIScrollView des séjours où je laisse aller. Après c'est fini de rechargement, l' UIScrollView saute vers le haut, pas d'animation.

Voici mon code:

 -(void)viewDidLoad
 {
      UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
      [refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
      [myScrollView addSubview:refreshControl];
 }

 -(void)handleRefresh:(UIRefreshControl *)refresh {
      // Reload my data
      [refresh endRefreshing];
 }

Est-il possible que je peux économiser un tas de temps, et d'utiliser un UIRefreshControl en UIScrollView?

Merci!!!!!!

95voto

Log139 Points 2170

J'ai eu un UIRefreshControl de travailler avec un UIScrollView:

- (void)viewDidLoad
{
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
    scrollView.userInteractionEnabled = TRUE;
    scrollView.scrollEnabled = TRUE;
    scrollView.backgroundColor = [UIColor whiteColor];
    scrollView.contentSize = CGSizeMake(500, 1000);

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    [refreshControl addTarget:self action:@selector(testRefresh:) forControlEvents:UIControlEventValueChanged];
    [scrollView addSubview:refreshControl];

    [self.view addSubview:scrollView];
}

- (void)testRefresh:(UIRefreshControl *)refreshControl
{    
    refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refreshing data..."];

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [NSThread sleepForTimeInterval:3];

        dispatch_async(dispatch_get_main_queue(), ^{
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            [formatter setDateFormat:@"MMM d, h:mm a"];
            NSString *lastUpdate = [NSString stringWithFormat:@"Last updated on %@", [formatter stringFromDate:[NSDate date]]];

            refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdate];

            [refreshControl endRefreshing];

            NSLog(@"refresh end");
        });
    });
}

Besoin de faire la mise à jour des données sur un thread séparé ou il bloque le thread principal (dont l'INTERFACE utilisateur utilise pour mettre à jour l'INTERFACE utilisateur). Ainsi, alors que le thread principal est occupé à mettre à jour les données, l'INTERFACE utilisateur est également verrouillé ou congelés et vous ne voyez jamais la douceur des animations ou spinner.

EDIT: ok, je suis en train de faire la même chose que l'OP et j'ai ajouté un peu de texte (c'est à dire, de "Tirer pour Rafraîchir") et il n'est besoin de revenir sur le thread principal de mettre à jour ce texte.

Mise à jour de réponse.

43voto

Diego Frata Points 399

Ajouter aux réponses ci-dessus, dans certaines situations, vous ne pouvez pas définir la contentSize (en utilisant la mise en page automatique peut-être?) ou la contentSize la hauteur est inférieure ou égale à la hauteur de la UIScrollView. Dans ces cas, la UIRefreshControl ne fonctionnera pas parce que les UIScrollView ne sera pas rebondir.

Pour résoudre ce définissez la propriété alwaysBounceVertical de VRAI.

11voto

John Gavilan Points 21

Voici comment le faire en C# / Monotouch. Je ne peux pas trouver tous les échantillons pour le C# n'importe où, si elle est ici.. Merci Log139!

public override void ViewDidLoad ()
{
    //Create a scrollview object
    UIScrollView MainScrollView = new UIScrollView(new RectangleF (0, 0, 500, 600)); 

    //set the content size bigger so that it will bounce
    MainScrollView.ContentSize = new SizeF(500,650);

    UIRefreshControl refresh = new UIRefreshControl();
    refresh.AddTarget(RefreshEventHandler,UIControlEvent.ValueChanged);
    MainScrollView.AddSubview (refresh);
}

private void RefreshEventHandler (object obj, EventArgs args)
{
System.Threading.ThreadPool.QueueUserWorkItem ((callback) => {  
    InvokeOnMainThread (delegate() {
    System.Threading.Thread.Sleep (3000);             
            refresh.EndRefreshing ();
    });
});
}

-3voto

Vous pouvez simplement créer une instance de l'actualisation de contrôle et de l'ajouter en haut de défilement de la vue. ensuite, le délégué des méthodes, vous pouvez l'ajuster son comportement.

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