29 votes

UIRefreshControl décalage incorrect du titre lors de la première exécution et parfois titre manquant

Le texte est mal décalé lors du premier lancement de UIRefreshControl... plus tard, il arrive que le texte d'actualisation n'apparaisse pas du tout et que seul l'épine soit visible.

Je ne pense pas avoir eu ce problème avec iOS6... cela pourrait être lié à iOS7

Se trouve dans un UITableViewController ajouté en tant qu'enfant à un VC, qui réside dans un UINavigationController présenté sous forme de modale

- (void)viewDidLoad {

    [super viewDidLoad];

    [self setRefreshControlText:@"Getting registration data"];
    [self.refreshControl beginRefreshing];
}

- (void)setRefreshControlText:(NSString *)text {

    UIFont * font = [UIFont fontWithName:@"Helvetica-Light" size:10.0];
    NSDictionary *attributes = @{NSFontAttributeName:font, NSForegroundColorAttributeName : [UIColor blackColor]};
    self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:text attributes:attributes];

}

enter image description here

enter image description here

39voto

Ben Jackson Points 407

Il s'agit bien d'un bug d'iOS 7, mais je n'en ai pas trouvé la cause exacte. Il semble que cela ait quelque chose à voir avec la hiérarchie des vues - l'ajout de mon UITableViewController en tant que vue enfant à un contrôleur de vue enveloppant a semblé le résoudre pour moi au début, bien que le bogue soit de retour depuis la GM d'iOS 7.

Il semble que l'ajout du code suivant à votre UITableViewController après la création de la vue de rafraîchissement règle définitivement le problème de positionnement :

dispatch_async(dispatch_get_main_queue(), ^{
    [self.refreshControl beginRefreshing];
    [self.refreshControl endRefreshing];
});

4voto

Edgar Points 522

En appelant endRefreshing sous viewWillAppear l'a fait pour moi :

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.refreshControl endRefreshing];
}

Sous iOS7 avec une UITableViewController à l'intérieur d'un UINavigationController

3voto

J'ai eu le même problème et pour moi ça a marché avec layoutIfNeeded après avoir défini l'attributTitle :

- (void)setRefreshControlText:(NSString *)text
{
    UIColor *fg = [UIColor colorWithWhite:0.4 alpha:1.0];
    NSDictionary *attrsDictionary = @{NSForegroundColorAttributeName: fg};
    self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:text attributes:attrsDictionary];
    [self.refreshControl layoutIfNeeded];
}

Cédric a suggéré d'utiliser [self.refreshControl setNeedsLayout] mais cela ne force pas une mise à jour immédiate de la vue, vous devez donc utiliser la fonction layoutIfNeeded .

2voto

Peter Lapisu Points 3274

J'ai enfin trouvé le Saint Graal sur ce sujet, qui semble fonctionner dans tous les cas

note : UIRefreshControl est ajouté à un UITableViewController (remarque, ne jamais ajouter UIRefreshControl comme une sous-vue d'un UIVIewController normal. UITableView ) (il est préférable d'ajouter UITableViewController comme un VC enfant à l'intérieur d'un UIViewController si vous le devez)

note : que cela corrige aussi le problème, que le UIRefreshControl n'est pas visible au premier rafraîchissement ( lien )

Ajoutez à votre .h

@interface MyViewController ()

@property (nonatomic, assign) BOOL refreshControlFixApplied;

- (void)beginRefreshing;
- (void)beginRefreshingWithText:(NSString *)text;
- (void)endRefreshing;
- (void)endRefreshingWithText:(NSString *)text;

@end

Ajoutez à votre .m

////////////////////////////////////////////////////////////////////////
#pragma mark - UIRefreshControl Fix (peter@min60.com) http://stackoverflow.com/questions/19121276/uirefreshcontrol-incorrect-title-offset-during-first-run-and-sometimes-title-mis/
////////////////////////////////////////////////////////////////////////

- (void)beginRefreshingWithText:(NSString *)text {

    [self setRefreshControlText:text];
    [self beginRefreshing];

}

- (void)endRefreshingWithText:(NSString *)text {

    [self setRefreshControlText:text];
    [self.refreshControl endRefreshing];

}

- (void)beginRefreshing {

    if (self.refreshControl == nil) {
        return;
    }

    if (!self.refreshControlFixApplied) {

        dispatch_async(dispatch_get_main_queue(), ^{

            if ([self.refreshControl.attributedTitle length] == 0) {
                [self setRefreshControlText:@" "];
            }
            [self.refreshControl beginRefreshing];

            dispatch_async(dispatch_get_main_queue(), ^{

                [self.refreshControl endRefreshing];

                dispatch_async(dispatch_get_main_queue(), ^{

                    // set the title before calling beginRefreshing
                    if ([self.refreshControl.attributedTitle length] == 0) {
                        [self setRefreshControlText:@" "];
                    }
                    if (self.tableView.contentOffset.y == 0) {
                        self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
                    }
                    [self.refreshControl beginRefreshing];

                    self.refreshControlFixApplied = YES;

                });

            });

        });

    } else {

        if (self.tableView.contentOffset.y == 0) {
            self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
        }
        [self.refreshControl beginRefreshing];

    }

}

- (void)endRefreshing {

    if (self.refreshControl == nil) {
        return;
    }

    if (!self.refreshControlFixApplied) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self endRefreshing];
        });
    } else {
        if (self.tableView.contentOffset.y < 0) {
            self.tableView.contentOffset = CGPointMake(0, 0);
        }
        [self.refreshControl endRefreshing];

    }

}

- (void)setRefreshControlText:(NSString *)text {

    UIFont * font = [UIFont fontWithName:@"Helvetica-Light" size:10.0];
    NSDictionary *attributes = @{NSFontAttributeName : font, NSForegroundColorAttributeName : [UIColor colorWithHex:0x00B92E]};
    self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:text attributes:attributes];

}

N'utilisez que des méthodes

- (void)beginRefreshing;
- (void)beginRefreshingWithText:(NSString *)text;
- (void)endRefreshing;
- (void)endRefreshingWithText:(NSString *)text;

1voto

Brett Points 293

Voici le code qui semble résoudre tous les problèmes. Beaucoup d'autres qui impliquaient le début ou la fin du rafraîchissement interféraient avec d'autres parties du contrôle.

//This chunk of code is needed to fix an iOS 7 bug with UIRefreshControls
static BOOL refreshLoadedOnce = NO;
if (!refreshLoadedOnce) {
  __weak typeof(self) weakself = self;
  [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
    self.tableView.contentOffset = CGPointMake(0, -weakself.refreshControl.frame.size.height);
  } completion:^(BOOL finished) {
    weakself.refreshControl.attributedTitle = self.refreshControl.attributedTitle;
    [weakself.refreshControl setNeedsUpdateConstraints];
    [weakself.refreshControl setNeedsLayout];
    refreshLoadedOnce = YES;
  }];
}
//End of bug fix

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