IOS 7 UIRefreshControl tintColor не работает для beginRefreshing

Я пытаюсь установить tintColor на мой UIRefreshControl (создание на iOS 7). Я включил обновление для TableViewController в раскадровке, затем в моем методе ViewController viewDidLoad я сделал следующее:

[self.refreshControl setTintColor:[UIColor redColor]];

Итак, теперь, когда я пытаюсь обновить, цвет элемента управления обновлением действительно красный:

redSpiny

Я хочу, чтобы мой просмотр автоматически обновлялся, когда он появился, поэтому я сделал:

- (void)viewDidAppear:(BOOL)animated{
    [self.refreshControl beginRefreshing];
}

Он не показывал вращающееся колесо, согласно qaru.site/info/63488/..., я добавил

[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:NO];

чтобы показать это. Он показывает это, но теперь он возвращается к цвету по умолчанию:

enter image description here

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

Я попытался создать его на iOS6, и он работает так, как должен, так же как и ошибка iOS7?

P.S.: это не проблема с симулятором, я пытался создать его на устройстве, такую ​​же ошибку.

P.P.S: Я построил примерный проект, можете ли вы сказать мне, есть ли у вас такая же ошибка или если в моем коде есть проблемы? Вот ссылка: http://d.pr/f/pGrV

Спасибо большое!

Ответ 1

Эй просто наткнулся на эту точную проблему.

Интересно, что я исправил свой код, сначала установив contentOffset, а затем запустив beginRefreshing

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

Вы можете оживить этот процесс:

[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
    self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
} completion:^(BOOL finished) {
    [self.refreshControl beginRefreshing];
}];

Надеюсь, это поможет вам.

Ш

Ответ 2

РЕШЕНИЕ SWIFT! Вставьте следующий код в viewDidLoad:

self.refreshControl.tintColor = UIColor.orangeColor()
self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height)
self.refreshControl.beginRefreshing()

Swift 3.1

self.refreshControl.tintColor = UIColor.orange
self.tableView.contentOffset = CGPoint(x:0, y:-self.refreshControl.frame.size.height)
self.refreshControl.beginRefreshing()

Ответ 3

@william-george ответ поставил меня в правильном направлении, но дал мне странные проблемы с анимацией автоопределения.

Итак, вот версия, которая работала для меня:

- (void)programaticallyRefresh {
    // Hack necessary to keep UIRefreshControl tintColor
    [self.scrollView setContentOffset:CGPointMake(0, -1.0f) animated:NO];
    [self.scrollView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];
    [self.refreshControl beginRefreshing];
    [self refresh];
}

-refresh - это метод, связанный с UIRefreshControl.

Ответ 4

Ни один из этих ответов не работает для меня правильно на iOS8, причем ближайший из них является ответом @jpsim, но он все еще оставил неприглядный черный контроль обновления во время его постепенной анимации (он будет пересекать границу между черным и в то время как на протяжении курса анимации).

Решение, которое сработало для меня, заключалось в том, чтобы сразу же установить его после создания элемента управления обновлением в моем представленииDidLoad:

self.refreshControl = [[UIRefreshControl alloc] init];
self.refreshControl.tintColor = [UIColor whiteColor];
...
self.refreshControlHeight = self.refreshControl.frame.size.height;
[self.tableView setContentOffset:CGPointMake(0, -1) animated:NO];
[self.tableView setContentOffset:CGPointMake(0, 0) animated:NO];

Затем, чтобы программно отобразить UIRefreshControl:

[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControlHeight) animated:YES];
[self.refreshControl beginRefreshing];

Мне нужно было сохранить высоту элемента управления обновлением, так как пока он был установлен для первого вызова, последующие вызовы имели бы высоту 0.

Ответ 5

СВИФТ:

Я использую Swift и > iOS8. Большинство описанных обходных решений для меня не работало. Это как я получил его работу:

В viewDidLoad:

customRefreshControl.tintColor = UIColor.clearColor()

В viewDidLoad не обязательно находиться следующее. Я поместил его в дополнительную функцию, которая вызывается каждый раз, когда я обновляю tableView:

private func startRefreshControlAnimation() {

    self.tableView.setContentOffset(CGPointMake(0, -self.customRefreshControl.frame.size.height), animated: true)

    CATransaction.begin()
    self.customRefreshControl.beginRefreshing()
    CATransaction.commit()

}

Ответ 6

Я объединил некоторые из предыдущих ответов. Это работает для меня на iOS 9 и Swift 2:

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    let contentOffset = self.tableView.contentOffset.y
    UIView.animateWithDuration(0, delay: 0, options: .BeginFromCurrentState, animations: {
        print(self.tableView.contentOffset.y)
            self.tableView.setContentOffset(CGPointMake(0, -self.refreshControl.frame.size.height), animated: false)
        }, completion: { finished in
            self.refreshControl.beginRefreshing()
            self.tableView.setContentOffset(CGPointMake(0, contentOffset/2-self.refreshControl.frame.size.height), animated: true)
            self.refresh() // Code that refresh table data
    })        
}

Ответ 7

Решение проблемы с tintColor: добавьте это в viewDidLoad

[self.refreshControl setTintColor:[UIColor whiteColor]];
[self.refreshControl tintColorDidChange];

Теперь у вас есть белый индикатор, когда вы вызываете beginRefresh вручную.

Ответ 8

Добавьте расширение для UIResfreshControl.

extension UIRefreshControl {
    func beginRefreshingManually() {
        self.tintColor = UIColor.white
        if let scrollView = superview as? UIScrollView {
            scrollView.setContentOffset(CGPoint(x: 0, y:scrollView.contentOffset.y - frame.height), animated: false)
        }
        beginRefreshing()
    }
}

Ответ 9

Я разрабатываю для iOS с помощью Xamarin (С#) и сталкивался с той же проблемой.

Я исправил проблему окраски, установив AttributedTitle в RefreshControl:

private CGPoint originalOffset;
...
public override void ViewDidLoad ()
{
     base.ViewDidLoad ();
     ...
     originalOffset = TableView.ContentOffset; // Store the original offset of the table view
     RefreshControl = new UIRefreshControl (){ TintColor = UIColor.Red };
     RefreshControl.ValueChanged += ((s,e) => { Update (this, EventArgs.Empty); });
     // Hack so the TintColor of the RefreshControl will be properly set
     RefreshControl.AttributedTitle = new NSAttributedString ("Fetching data");
}

Мой метод обновления выглядит следующим образом:

private async void Update(object sender, EventArgs args)
{
     try {
          TableView.UserInteractionEnabled = false;
          // I find -100 to be a big enough offset
          TableView.SetContentOffset (new CGPoint (0, -100), true);
          RefreshControl.BeginRefreshing ();
          ... // Fetch data & update table source 
          TableView.ReloadData ();
      } catch(Exception) {
          // Respond to exception
      } finally {
          // Put the offset back to the original
          TableView.SetContentOffset (originalOffset, true);
          RefreshControl.EndRefreshing ();
          TableView.UserInteractionEnabled = true;
      }
}

После ViewDidAppear, я вызываю Update программно. Перед установкой присвоенного названия мой счетчик был бы черным. Теперь он имеет правильный красный цвет.

Стоит заметить, что этот "взлом/исправление" также имеет вторую ошибку. При первом обновлении вы заметите, что AttributedTitle не отображается. Обновление второго (, третьего, четвертого,...) времени отобразит заголовок правильно. Но если вам не нужен заголовок, вы просто инициализируете его пустой строкой, и это не является большой проблемой для вас.

Я надеюсь, что это может пригодиться другим.

Ответ 10

этот хак очень работает

var refreshWasProgramBeginning: Bool = false

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if !refreshWasProgramBeginning {
        UIView.animate(withDuration: 0.25, animations: {
            self.tableView.contentOffset = CGPoint.init(x: 0, y: -self.refreshControl.frame.height)
        }) { (_) in
            self.refreshControl.beginRefreshing()
            self.refreshWasProgramBeginning = true
        }
    }
}

Ответ 11

Попробуйте установить tintColor вашего UIRefreshControl в viewWillAppear.

Ответ 12

Я нашел несколько Work Around, надеюсь, он сработает для вас.

 [_TBL setContentOffset:CGPointMake(0,_TBL.contentOffset.y-_refreshControl.frame.size.height) animated:YES];
[_refreshControl performSelector:@selector(beginRefreshing) withObject:nil afterDelay:0.25];
[self getLatestUpdates];

Ответ 13

Я создал drop-in категорию UIRefreshControl + beginRefreshing, которая устраняет эту проблему.

Вкратце, он исправляет проблему tintColor и вручную tableView корректирует contentOffset, чтобы убедиться, что элемент управления обновлением виден. Попробуйте:)

Ответ 14

Я работаю с Xamarin С# (iOS 10) и обнаружил, что комбинация всех этих ответов - это то, что исправлено для меня.

В моем ViewDidLoad у меня есть следующее:

    RefreshControl = new UIRefreshControl();
    RefreshControl.TintColor = UIColor.White;
    RefreshControl.ValueChanged += OnRefresh;
    RefreshControl.BackgroundColor = UIColor.Clear;

И позже я программно вызываю анимацию обновления в своем ViewDidAppear со следующим:

    BeginInvokeOnMainThread(() =>
    {
        UIView.Animate(0, 0.2, UIViewAnimationOptions.BeginFromCurrentState, () =>
        {
            TableView.SetContentOffset(new CGPoint(0, TableView.ContentOffset.Y - RefreshControl.Frame.Size.Height), true);
            RefreshControl.AttributedTitle = new NSAttributedString("");
        },
        () =>
        {
            RefreshControl.BeginRefreshing();
        });
    });

Обратите внимание, что настройка атрибутного заголовка и блока анимации была теми частями, которые мне не хватало для моего RefreshControl, чтобы взять мой белый цвет оттенка.

Спасибо всем, кто внес свой вклад в этот вопрос.

Ответ 15

Это ошибка, которая возникает при вызове beginRefreshing() управления refresh сразу после установки его свойства tintColor (или при вызове его из viewDidLoad() (подробности здесь). Однако существует простой обходной путь, beginRefreshing() вызов beginRefreshing() внутри defer выражение (Swift 4):

override func viewDidLoad() {
    super.viewDidLoad()
    refreshControl.tintColor = .red
    defer {
        refreshControl.beginRefreshing()
    }
}

Ответ 16

Когда я установил

tableView.refreshControl = refreshControl 

Несколько раз, когда refreshControl был другим экземпляром каждый раз, у меня возникала проблема, когда цвет элемента управления обновлением всегда был черным, а настройка цвета оттенка на другое значение не помогала.

Так что я устанавливаю tableView.refreshControl = refreshControl только один раз, и когда мне нужно скрыть его, я устанавливаю альфа-значение, подробнее в этой теме:

Как мне "спрятать" UIRefreshControl?

Ответ 17

Использование UIView.animate не работает для меня на Swift 4.

Вот что я в итоге использовал

extension UIRefreshControl {
    func beginRefreshingManually(with scrollView: UIScrollView, isFirstTime: Bool) {
        if self.isRefreshing { return }

        // Workaround: If we call setContentOffset on the first time that the screen loads
        // we get a black refreshControl with the wrong size.
        // We could just set the scrollView.contentOffset everytime, but it does not animate the scrolling.
        // So for every other time, we call the setContentOffset animated.
        if isFirstTime {
            scrollView.contentOffset = CGPoint(x: 0, y: -self.frame.size.height)
        } else {
            scrollView.setContentOffset(CGPoint(x: 0, y: -self.frame.size.height), animated: true)
        }
        self.beginRefreshing()
    }
}

Ответ 18

Установите ручное смещение содержимого для вашего tableView/scrollView перед началом вращения:

tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)
refreshControl.beginRefreshing()
......

Ответ 19

Принудите setTintColor для запуска в основном потоке. (Основная нить обновляет ui).

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    [self.refreshControl setTintColor:[UIColor redColor]];
    [self.refreshControl beginRefreshing];
}];