UIRefreshControl(iOS 7でビルド)でtintColorを設定しようとしています。ストーリーボードでtableViewControllerの更新を有効にし、ViewController viewDidLoad
メソッドで次のことを行いました。
[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のバグですか?
追伸:これはシミュレーターの問題ではなく、同じバグをデバイス上でビルドしてみました。
P.P.S:サンプルプロジェクトを作成しましたが、同じバグがあるのか、コードに問題があるのか教えてもらえますか?リンクは次のとおりです。 http://d.pr/f/pGrV
どうもありがとう !
ちょっと、ちょうどこの問題につまずいた。
興味深いことに、まず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
迅速な解決策! 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()
@ 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
に関連付けられたメソッドです。
これらの答えはどれも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になるためです。
迅速:
私はSwift and> 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()
}
TintColorの問題の解決策:これをviewDidLoadに追加します
[self.refreshControl setTintColor:[UIColor whiteColor]];
[self.refreshControl tintColorDidChange];
BeginRefreshを手動で呼び出すと、白いインジケーターが表示されます。
以前の回答のいくつかを組み合わせました。これは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
})
}
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()
}
}
このハックは非常に効果的です
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
}
}
}
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
をプログラムで呼び出します。属性タイトルを設定する前は、スピナーは黒だったでしょう。これで適切な赤色になりました。
この「ハック/修正」には2番目のバグもあることに注意してください。初めて更新すると、AttributedTitle
が表示されないことがわかります。 2番目(、3番目、4番目、...)の時間を更新すると、タイトルが正しく表示されます。ただし、タイトルが必要ない場合は、空の文字列で初期化するだけです。これは大きな問題ではありません。
これが他の人にも役立つことを願っています。
この問題を修正するドロップイン IRefreshControl + beginRefreshing category を作成しました。
簡単に言うと、tintColorの問題を修正し、手動でtableViewがcontentOffsetを調整して、更新コントロールが表示されるようにします。してみてください :)
設定するとき
tableView.refreshControl = refreshControl
何回か、refreshControlが毎回異なるインスタンスである場合、リフレッシュコントロールの色が常に黒で、色合いの色を異なる値に設定しても問題が解決しませんでした。
tableView.refreshControl = refreshControl
を1回だけ設定し、非表示にする必要がある場合は、このスレッドで詳細をアルファ値に設定します。
これは、tintColor
プロパティを設定した直後にリフレッシュコントロールでbeginRefreshing()
を呼び出した場合(またはviewDidLoad()
から呼び出した場合に発生するバグです(詳細 こちら )。ただし、defer
ステートメント内にbeginRefreshing()
呼び出しをラップすることにより、簡単な回避策があります(Swift 4):
override func viewDidLoad() {
super.viewDidLoad()
refreshControl.tintColor = .red
defer {
refreshControl.beginRefreshing()
}
}
ViewWillAppearでUIRefreshControlのtintColorを設定してみてください。
私は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
が白い色合いをとるために欠けていた部分でした。
この質問に貢献してくれたすべての人に感謝します。
スピンを開始する前に、tableView/scrollViewのコンテンツオフセットを手動で設定します。
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)
refreshControl.beginRefreshing()
......
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()
}
}
いくつかの回避策を見つけました
[_TBL setContentOffset:CGPointMake(0,_TBL.contentOffset.y-_refreshControl.frame.size.height) animated:YES];
[_refreshControl performSelector:@selector(beginRefreshing) withObject:nil afterDelay:0.25];
[self getLatestUpdates];