Le texte est décalé de manière erronée lors du premier lancement de UIRefreshControl ... plus tard, parfois, le texte d'actualisation n'apparaît pas du tout et seule l'épine est visible
Je ne pense pas que j'ai eu ce problème avec iOS6 ... pourrait être lié à iOS7
Est dans un UITableViewController ajouté en tant qu'enfant à un VC, qui réside dans un UINavigationController présenté sous forme 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];
}
Il s’agit bien d’un bogue iOS 7, mais je n’ai pas trouvé exactement ce qui l’a causé. Cela semble avoir quelque chose à voir avec la hiérarchie des vues - l'ajout de mon UITableViewController en tant que vue enfant à un contrôleur de vue wrapper a semblé résoudre le problème pour moi au début, bien que le bogue soit de retour depuis iOS 7 GM.
Il semble que l'ajout du code suivant à votre UITableViewController après la création de la vue d'actualisation résout le problème de positionnement de manière définitive:
dispatch_async(dispatch_get_main_queue(), ^{ [self.refreshControl beginRefreshing]; [self.refreshControl endRefreshing]; });
appeler endRefreshing
sous viewWillAppear
l'a fait pour moi:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.refreshControl endRefreshing];
}
Sous iOS7 avec une UITableViewController
personnalisée dans une UINavigationController
J'ai eu le même problème et pour moi, cela fonctionnait avec layoutIfNeeded
après la définition du 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 layoutIfNeeded
.
UIRefreshControl semble toujours être endommagé sur IOS9.3 lorsque vous modifiez le attributTitle lorsque la tableView est déroulée. Ce qui semble fonctionner est de sous-classer UIRefreshControl et de forcer la mise à jour de sa présentation une fois que le titre (attribué) a été modifié. les sous-vues de spinner et de texte) et de forcer la hauteur du cadre à la valeur attendue en veillant à ce que la couleur d'arrière-plan remplisse la zone déroulée.
@implementation MEIRefreshControl
{
__weak UITableView* _tableView;
}
- (instancetype)initWithTableView:(UITableView*)tableView
{
self = [super initWithFrame:CGRectZero];
if (self)
{
_tableView = tableView;
}
return self;
}
@synthesize title = _title;
- (void)setTitle:(NSString *)title
{
if (!PWEqualObjects(_title, title))
{
_title = title;
self.attributedTitle = [[NSAttributedString alloc] initWithString:_title ? _title : @""];
[self forceUpdateLayout];
}
}
- (void)forceUpdateLayout
{
CGPoint contentOffset = _tableView.contentOffset;
_tableView.contentOffset = CGPointZero;
_tableView.contentOffset = contentOffset;
CGRect frame = self.frame;
frame.size.height = -contentOffset.y;
self.frame = frame;
}
@end
J'ai finalement trouvé le Saint Graal à ce sujet, qui semble fonctionner dans tous les cas
note: UIRefreshControl
est ajouté à UITableViewController
(remarque, n'ajoutez jamais UIRefreshControl
juste comme sous-vue à un UITableView
de UIVIewController normal) (il est préférable d'ajouter UITableViewController
en tant qu'enfant VC dans UIViewController
si
note: que cela corrige aussi le problème, que l'UIRefreshControl n'est pas visible au premier rafraîchissement ( link )
Ajouter à vous .h
@interface MyViewController ()
@property (nonatomic, assign) BOOL refreshControlFixApplied;
- (void)beginRefreshing;
- (void)beginRefreshingWithText:(NSString *)text;
- (void)endRefreshing;
- (void)endRefreshingWithText:(NSString *)text;
@end
Ajouter à vous .m
////////////////////////////////////////////////////////////////////////
#pragma mark - UIRefreshControl Fix ([email protected]) https://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];
}
Utilisez uniquement des méthodes
- (void)beginRefreshing;
- (void)beginRefreshingWithText:(NSString *)text;
- (void)endRefreshing;
- (void)endRefreshingWithText:(NSString *)text;
C'est 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
J'ai eu le même problème, je l'ai résolu en définissant un texte attribué avec une chaîne d'espace pour actualiser le contrôle directement après le contrôle d'actualisation init
_refreshControl = [[UIRefreshControl alloc]init];
[_refreshControl setAttributedTitle:[[NSAttributedString alloc]initWithString:@" "]];
Après cela, la définition d'un nouveau texte attribué pour actualiser le contrôle s'est déroulée sans aucun problème.
[[self refreshControl] setAttributedTitle:[[NSAttributedString alloc]initWithString:[NSString stringWithFormat:@"Последнее обновление: %@", [dateFormat stringFromDate:[_post dateUpdated]]]]];
METTRE &AGRAVE; JOUR
J'ai remarqué que le problème revenait lorsque j'utilisais attrsDictionary:
ce code fonctionne bien
NSAttributedString* attributedString = [[NSAttributedString alloc]initWithString:string];
[[self refreshControl] setAttributedTitle: attributedString];
et cela fait apparaître le titre de refreshControl directement après l'affichage chargé
NSAttributedString* attributedString = [[NSAttributedString alloc]initWithString:string attributes:attrsDictionary];
[[self refreshControl] setAttributedTitle: attributedString];
Je n'ai pas encore trouvé de solution.
METTRE &AGRAVE; JOUR
La solution finalement trouvée, après refreshcontrol init, définit également la chaîne attribuée avec des attributs: attrsDictionary
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects:[UIColor appDarkGray], [UIFont fontWithName:@"OpenSans-CondensedLight" size:14.0f], nil] forKeys:
[NSArray arrayWithObjects:NSForegroundColorAttributeName, NSFontAttributeName, nil]];
[_refreshControl setAttributedTitle:[[NSAttributedString alloc]initWithString:@" " attributes:attrsDictionary]];
donc après cela, il n'y a plus de problème pour définir le titre du nouveau refreshcontrol.
La solution pour moi était de définir un texte dans viewDidAppear
, inutile d'appeler
beginRefreshing
ou endRefreshing
dans la file d'attente principale
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"d MMM, HH:mm"];
NSString *lastUpdated = [NSString stringWithFormat:NSLocalizedString(@"refresh_last_updated", nil),[formatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:[[[DatabaseController sharedInstance] getCurrentSettings].lastTimeStamp doubleValue]]]];
UIFont *font = [UIFont fontWithName:FONT_LATO_LIGHT size:12.0f];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:lastUpdated attributes:@{NSFontAttributeName:font}];
_refreshControl.attributedTitle = attrString;
}