データの読み込みが完了し、tableViewが再読み込みされたら、更新コントロールでendRefreshingを呼び出し、読み込み状態から「ジャンプ」して非表示にします。更新コントロールが完了したときにスライドして滑らかなアニメーションを実行する方法を教えてください。 ?
説明が正確ではないので、新しい答えを追加します。そして、これはおそらくコメントには多すぎるでしょう。
Halpo による解は正しいです。しかし、言及された理由は間違っています。
-[NSObject (NSDelayedPerforming) performSelector:withObject:afterDelay:]
を呼び出すと、呼び出しが次のrunloop反復で実行されることが保証されます。
したがって、少し遅延があるため、これは機能しませんが、次のループに移動しています。
実際には、遅延を0.0
に減らすことができますが、それでも機能します。また、より正確な(結果の改善ではなく、何かを達成するためのオブジェクトの使用に関して)実装が可能です。
そのためのさまざまなコードスニペットを次に示します。
// SOLUTION I
[[self tableView] reloadData];
[[self refreshControl] performSelector:@selector(endRefreshing) withObject:nil afterDelay:0.0];
// SOLUTION II (semantically correct)
[[self tableView] reloadData];
[[NSOperationQueue currentQueue] addOperationWithBlock:^{
[[self refreshControl] endRefreshing];
}];
// SOLUTION III (GCD)
dispatch_async(dispatch_get_main_queue(), ^{
[[self refreshControl] endRefreshing];
}];
[〜#〜]編集[〜#〜]
johann-fradj が指摘したように、GCDを使用することもできます。私はGCDが大好きですが、ソリューションIIは何が起こっているかを最もよく説明しています。また、GCDはあまりObjective-C風ではないので、個人的には自分の解決策に固執したいと思います。
問題を修正しました-データを再ロードした後、endRefreshに小さな遅延を追加しました:
[self.tableView reloadData];
[self.refreshControl performSelector:@selector(endRefreshing) withObject:nil afterDelay:0.05];
Swift 4ソリューション
tableView.reloadData()
if refreshControl?.isRefreshing == true {
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
}
その他のソリューション(遅延、CATransactionの使用など)はより複雑であり、目に見える利点はありません
endRefreshing()
の呼び出しをUIViewアニメーションブロックにラップしてみてください。
私もこの問題に遭遇しました。 endRefreshing()
の場合、ドキュメントには次のように記載されています。
UIView.animateWithDuration(0.5) {
self.refreshControl.endRefreshing()
}
ドキュメントは述べています:
アニメーションも有効な場合、コントロールはアニメーションを使用して非表示になります。
理由の1つは、endRefreshが呼び出された後にテーブルビューを更新することです。たとえば、私の呼び出しは次のようになりました:
[self.refreshControl beginRefreshing];
[self.network getThings:^(id things, NSError *error) {
[self.refreshControl endRefreshing];
if (error) {
...
} else {
self.things = things;
[self.tableView reloadData];
}
}];
EndRefreshアニメーションの実行中にテーブルが自動的に更新されるため、これは悪いことです。したがって、正しく行われたコードは次のようになります。
[self.refreshControl beginRefreshing];
[self.network getThings:^(id things, NSError *error) {
if (error) {
[self.refreshControl endRefreshing];
...
} else {
self.things = things;
[self.tableView reloadData];
[self.refreshControl endRefreshing];
}
}];
私にとっての解決策は、refreshControl?.endRefreshing()
beforetableView.reloadData()
への呼び出しを実行することでした:
_refreshControl?.endRefreshing()
tableView.reloadData()
_
endRefreshing()
の呼び出しがreloadData()
の呼び出しの後だった場合、データが再ロードされるたびにTableViewがジャンプしました。