Подтвердить что ты не робот

UIRefreshControl неправильное смещение названия во время первого запуска, а иногда и название отсутствует

Текст смещен неправильно при первом запуске UIRefreshControl... позже иногда текст обновления не отображается вообще, и только колючие видимы

Я не думаю, что у меня была эта проблема с iOS6... может быть связана с iOS7

Является в UITableViewController, добавленном как дочерний элемент в VC, который находится в модальном представленном UINavigationController

- (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

4b9b3361

Ответ 1

Это определенно ошибка iOS 7, но я не понял, что именно это вызвало. Похоже, что это имеет какое-то отношение к иерархии представлений - добавление моего UITableViewController в виде дочернего представления к контроллеру представления оболочки, по-видимому, исправило его для меня сначала, хотя ошибка вернулась с iOS 7 GM.

Похоже, что добавление следующего кода в ваш UITableViewController после создания представления обновления фиксирует проблему позиционирования навсегда:

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

Ответ 2

вызов endRefreshing под viewWillAppear сделал это для меня:

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

    [self.refreshControl endRefreshing];
}

В iOS7 с пользовательским UITableViewController внутри UINavigationController

Ответ 3

У меня была такая же проблема, и для меня она работала с layoutIfNeeded после установки атрибута Title:

- (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];
}

Седрик предложил использовать [self.refreshControl setNeedsLayout], но это не приводит к немедленному обновлению представления, поэтому вы должны использовать layoutIfNeeded.

Ответ 4

Наконец я нашел святого Грааля, который выглядит во всех случаях

note: UIRefreshControl добавляется к UITableViewController (обратите внимание, никогда не добавляйте UIRefreshControl так же, как subview в обычный UIVIewController UITableView) (лучше добавить UITableViewController в качестве дочернего VC внутри a UIViewController если вам нужно)

Примечание: , что это также устраняет проблему, что UIRefreshControl недопустимо при первом обновлении (ссылка)

Добавить к тебе .h

@interface MyViewController ()

@property (nonatomic, assign) BOOL refreshControlFixApplied;

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

@end

Добавить к тебе .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];

}

Использовать только методы

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

Ответ 5

UIRefreshControl, по-прежнему, по-прежнему разбивается на IOS9.3, когда вы меняете атрибут title, когда tableView сбрасывается. Кажется, что работает подкласс UIRefreshControl и принудительно обновляет его компоновку после изменения названия (атрибута). Основное исправление заключается в том, чтобы вызвать изменение в tableView contentOffset (вызывая некоторую скрытую магию в методе _update, который макетирует прядильщик и текстовые подзаголовки) и дополнительно заставляя высоту кадра соответствовать ожидаемому значению, обеспечивающему, чтобы цвет фона заполнял область выталкивания.

@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

Ответ 6

Это код, который, как представляется, устраняет все проблемы. Многие из других, которые включали начало или окончание освежения, где мешали другим частям контроля.

//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

Ответ 7

У меня была та же проблема, я решил ее, установив атрибутный текст с помощью строки пробела, чтобы обновить элемент управления непосредственно после элемента управления обновлением обновления

_refreshControl = [[UIRefreshControl alloc]init];
[_refreshControl setAttributedTitle:[[NSAttributedString alloc]initWithString:@" "]];

После этого установка нового атрибута текста для обновления управления была без проблем.

[[self refreshControl] setAttributedTitle:[[NSAttributedString alloc]initWithString:[NSString stringWithFormat:@"Последнее обновление: %@", [dateFormat stringFromDate:[_post dateUpdated]]]]];

UPDATE

Я заметил, что проблема возникает, когда я использую attrsDictionary:

этот код отлично работает

NSAttributedString* attributedString = [[NSAttributedString alloc]initWithString:string];
[[self refreshControl] setAttributedTitle: attributedString];

и это заставляет заголовок refreshControl отображаться непосредственно после просмотра загруженного

NSAttributedString* attributedString = [[NSAttributedString alloc]initWithString:string attributes:attrsDictionary];
[[self refreshControl] setAttributedTitle: attributedString];

Я еще не нашел решение.

UPDATE

Наконец нашел решение, после того, как refreshcontrol init установил атрибутированную строку также с атрибутами: 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]];

поэтому после этого нет проблемы с установкой нового заголовка refreshcontrol.

Ответ 8

Решение для меня заключалось в том, чтобы установить текст в viewDidAppear, не нужно вызывать

beginRefreshing или endRefreshing в mainQueue

-(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;
}

Ответ 9

Используете ли вы свойство refreshcontrol для UITableViewController? Вы не должны устанавливать его как дочерний.