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]()
Ответы
Ответ 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? Вы не должны устанавливать его как дочерний.