76

我正在尝试在我的 UIRefreshControl 上设置一个 tintColor(在 iOS 7 上构建)。我在情节提要中启用了 tableViewController 的刷新,然后在我的 ViewControllerviewDidLoad方法中执行了以下操作:

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

所以现在,当我拉刷新时,刷新控件的颜色确实是红色:

红色刺

我希望我的视图在出现时自动更新,所以我这样做了:

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

根据https://stackoverflow.com/a/16250679/1809736 ,它没有显示纺车,我补充说

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

强制显示它。它显示它,但现在它恢复为默认颜色:

在此处输入图像描述

如果我之后尝试手动拉动刷新,它是红色的。

我尝试在 iOS6 上构建它,它应该可以正常工作,那是 iOS7 的错误吗?

PS:模拟器没有问题,我尝试在设备上构建它,同样的错误。

PPS:我建立了一个示例项目,你能告诉我你是否有同样的错误,或者我的代码是否有问题?这是链接:http ://d.pr/f/pGrV

非常感谢 !

4

19 回答 19

54

嘿只是偶然发现了这个确切的问题。

有趣的是,我通过先设置 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];
}];

希望这对您有所帮助。

W

于 2013-12-04T18:27:06.997 回答
28

快速解决方案!在 中插入以下代码viewDidLoad

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

斯威夫特 3.1

self.refreshControl.tintColor = UIColor.orange
self.tableView.contentOffset = CGPoint(x:0, y:-self.refreshControl.frame.size.height)
self.refreshControl.beginRefreshing()
于 2015-07-04T19:13:39.593 回答
8

@william-george 的回答让我朝着正确的方向前进,但给了我奇怪的自动布局动画问题。

所以这是对我有用的版本:

- (void)programaticallyRefresh {
    // Hack necessary to keep UIRefreshControl's 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

于 2014-03-27T21:51:39.087 回答
7

为 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()
    }
}
于 2017-03-22T19:33:33.273 回答
4

这些答案都没有在 iOS8 上正确地为我工作,最接近的是@jpsim 的答案,但在淡入动画期间仍然留下难看的黑色刷新控件(它会在黑色和动画过程中交叉淡入淡出) )。

对我有用的解决方案是在我的 viewDidLoad 中创建刷新控件后立即放置:

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 高度。

于 2014-12-09T01:22:41.997 回答
3

tintColor 问题的解决方案:在 viewDidLoad 中添加

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

现在,当您手动调用 beginRefresh 时,您有一个白色指示器。

于 2014-04-03T15:56:51.563 回答
3

我结合了之前的一些答案。这适用于 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
    })        
}
于 2016-09-13T20:40:14.033 回答
3

迅速:

我正在使用 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()

}
于 2015-09-30T09:37:15.593 回答
2

我使用 Xamarin (C#) 为 iOS 开发并遇到了同样的问题。

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编程方式调用。在设置属性标题之前,我的微调器会是黑色的。现在它具有适当的红色。

值得注意的是,这个“hack/fix”还带有第二个错误。第一次刷新时,您会注意到AttributedTitle没有显示。刷新第二(,第三,第四,...)时间将正确显示标题。但是如果你不想要一个标题,你只需用一个空字符串来初始化它,这对你来说不是什么大问题。

我希望这对其他人有用。

于 2016-03-07T16:51:54.653 回答
1

我正在使用 Xamarin C# (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白色色调的部分。

感谢所有为这个问题做出贡献的人。

于 2017-10-10T16:39:37.693 回答
1

这个黑客非常有效

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
        }
    }
}
于 2016-10-24T08:10:41.010 回答
1

在开始旋转之前为您的 tableView/scrollView 手动设置内容偏移量:

tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)
refreshControl.beginRefreshing()
......
于 2019-04-09T12:50:45.677 回答
1

这是在设置属性beginRefreshing()后立即调用刷新控件时发生的错误(或从此处调用它(详情here )。但是,通过将调用包装在语句中(Swift 4)有一个简单的解决方法:tintColorviewDidLoad()beginRefreshing()defer

override func viewDidLoad() {
    super.viewDidLoad()
    refreshControl.tintColor = .red
    defer {
        refreshControl.beginRefreshing()
    }
}
于 2018-07-24T21:09:36.667 回答
0

我找到了一些解决方法我希望它对你有用

 [_TBL setContentOffset:CGPointMake(0,_TBL.contentOffset.y-_refreshControl.frame.size.height) animated:YES];
[_refreshControl performSelector:@selector(beginRefreshing) withObject:nil afterDelay:0.25];
[self getLatestUpdates];
于 2015-02-22T10:39:43.097 回答
0

尝试在 viewWillAppear 中设置 UIRefreshControl 的 tintColor。

于 2014-01-28T08:15:55.557 回答
0

我创建了一个嵌入式 UIRefreshControl+beginRefreshing 类别来解决此问题。

简而言之,它修复了 tintColor 问题并手动 tableView 调整 contentOffset 以确保刷新控件可见。请试试 :)

于 2015-06-03T08:46:49.787 回答
0

在 Swift 4 上使用UIView.animate对我不起作用。

这是我最终使用的

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()
    }
}
于 2019-02-04T03:25:26.563 回答
0

当我设置

tableView.refreshControl = refreshControl 

有几次 refreshControl 每次都是不同的实例时,我遇到了刷新控件颜色始终为黑色并且将色调颜色设置为不同值没有帮助的问题。

所以我tableView.refreshControl = refreshControl只设置了一次,当我需要隐藏它时,我设置了 alpha 值,这个线程中的更多细节:

如何“隐藏” UIRefreshControl?

于 2019-01-31T13:48:47.203 回答
-2

强制 setTintColor 在主线程中运行。(主线程更新 ui)。

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    [self.refreshControl setTintColor:[UIColor redColor]];
    [self.refreshControl beginRefreshing];
}];
于 2013-10-23T05:28:18.437 回答