UINavigationControllerのルートビューコントローラーとしてUITableViewControllerがあります。これは、UITabBarControllerのビューコントローラーの1つです。すべてストーリーボードに接続されています。
ストーリーボードでもテーブルのUIRefreshControlを構成しましたが、通常、プルすると次のようになります。
ただし、他のタブを1〜2回切り替えると、次のようになります。
回転していないか、「いっぱい」になっているだけで、完全に引っ張ってリフレッシュをトリガーするまでそのままです。
どんなアイデアや提案もありがたいです。
私はこれが信じられないほど遅いことを知っています、しかし私は決して遅くないよりよく理解します。
残念ながら、与えられた答えはどれも私にはうまくいきませんでした。動作したのは、viewWillAppearのこのひどいコードだけでした。
self.refreshControl = nil;
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(refreshFunction) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
基本的に、ビューが表示されるたびにUIRefreshControlを再作成します。次の警告を出している間は機能します。
アイドル状態でないときにリフレッシュコントロールを変更しようとすることは強くお勧めできません。おそらく正しく機能しません。
私は正直なところ、これがまだ問題であることに驚いています(iOS 9でもこれが見られます)。うまくいけば、これは他の人に役立つかもしれません。
user2009606はほぼ正しかったので、電話して修正しました
[refreshControl endRefreshing];
オン
viewWillAppear:
RefreshControlは、タブを切り替えた後、その状態に関係なく正しく動作するようになりました。
要約して、完全なソリューションを提供します。
問題:
画面遷移中にUIRefreshControlがアニメーション化されている場合、UIRefreshControlは表示されたままになりますが、アニメーション化されません。ビデオ https://vid.me/Bkb7
また、プルトゥリフレッシュアニメーションが開始されたが完了しておらず、その後トランジションが実行された場合、UIRefreshControlは非表示になりますがスタックします。ビデオ https://vid.me/Bkb7
解決:
ViewWillAppearでUIRefreshControlアニメーションを開始し、viewDidDisappearで終了します。更新プロセスの状態を保存して、UIRefreshControlをいつ表示するかを確認します。
ベローは、適切なアニメーションとアニメーションを更新するための単純なプルも処理するソリューション全体です。
UITableViewまたはサブクラスに追加
初期化:
/// Refresh indicator
var refreshControl = UIRefreshControl()
/// Refresh state
var isRefreshing = false
/// Refresh controll update funcion. Set to enable pull to refresh
var refreshControllUpdateFunction: (() -> ())?
/// Prepeares UIRefreshControll. Call from init
func initRefreshControl(){
addSubview(refreshControl)
refreshControl.addTarget(self, action: "refreshControllTarget", forControlEvents: .ValueChanged)
refreshControl.beginRefreshing()
isRefreshing = true
}
スーパービューイベントハンドラー:
/// Call on viewWillApper
func superviewWillApper(){
if isRefreshing && !refreshControl.refreshing{
startRefreshAnimation()
}
}
/// Call on viewDidDisapper
func superviewDidDisappear(){
endRefreshAnimation(false, dataFetched: !isRefreshing)
}
UIRefreshControlアニメーションハンドラー:
/// Presents animating UIRefreshControll
func startRefreshAnimation(){
refreshControl.beginRefreshing()
contentOffset = CGPointMake(0, -refreshControl.bounds.size.height)
isRefreshing = true
}
/// Hides UIRefreshControll and saves state of refresh
func endRefreshAnimation(wasEmpty: Bool, dataFetched: Bool){
refreshControl.endRefreshing()
isRefreshing = !dataFetched
if !wasEmpty{
setContentOffset(CGPointZero, animated: true)
}else{
setContentOffset(CGPointZero, animated: false)
}
}
追加
table.isRefreshing = true
リフレッシュ呼び出しの開始まで。
結果ビデオ https://vid.me/LyuI
次の解決策が役立つ場合があります。
CGFloat yTableViewOffset;
- (void)viewDidLoad {
yTableViewOffset = kNilOptions;
}
- (void)viewWillAppear:(BOOL)animated
{
if(yTableViewOffset != kNilOptions) {
CGPoint offset = CGPointMake(tableView.contentOffset.x, yTableViewOffset);
[refreshControl beginRefreshing];
tableView.contentOffset = offset;
}
}
- (void)viewWillDisappear:(BOOL)animated
{
if(refreshControl.isRefreshing) {
yTableViewOffset = tableView.contentOffset.y;
[refreshControl endRefreshing];
}
}
viewWillDisappear:
でendRefreshing
を呼び出すだけで、すべての問題が修正されました。
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.refreshControl endRefreshing];
}
viewWillAppear:
で同じことを行うと、テーブルを引っ張るときに更新コントロールが奇妙に回転しました。
私はちょうど同じことを見ました。私がやったことは、viewWillDisappearのendRefreshingであり、少なくともこの問題は解消されます。ただし、タブに戻ると、更新プロセスを再開してbeginRefreshingを再度呼び出すと、タブが再び回転し始めると思いますが、そうではありません。ナビゲーションをドリルダウンしてから戻ってきた場合も同様です。
リフレッシュコントロールが回転しているときに、他のコントローラーを提示して「リフレッシュの終了」の前に戻った場合。更新アニメーションがスタックします。
上記の答えはどれも私にはうまくいきませんでした、そして私はブール値を設定して、ViewControllerのすべてのライフサイクルを通してそれに従うことを望んでいませんでした。
私の解決策は、viewWillAppearの最後に以下のコードを追加することです。
objcで;
if (self.refreshControl.isRefreshing) {
[self.refreshControl endRefreshing];
[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated: true];
[self.refreshControl beginRefreshing];
}
swiftで;
if self.refreshControl.isRefreshing {
self.refreshControl.endRefreshing
self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.contentOffset.y-self.refreshControl.frame.size.height), animated: true)
self.refreshControl.beginRefreshing;
}
ロジックは;リフレッシュコントロールがアニメーションの状態にあることをキャッチすると、スタックしているかどうかを知らずに停止し、アニメーションを再実行します。
それが役に立てば幸い。
Swiftで最も優れた修正:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//fixes bug with refreshControl freezing while switching tabs
if tableView.contentOffset.y < 0 {
tableView.contentOffset = .zero
}
}
私がこの問題を最終的に解決するのを手伝うことができることを願っています:
Pull-To-RefreshコントロールでUITableViewを使用すると問題が発生します。これは、UITableViewControllerを追加することで簡単に解決できます。
UITableViewController *tableController = [[UITableViewController alloc] init];
tableController.automaticallyAdjustsScrollViewInsets = NO;
[tableController willMoveToParentViewController:self];
[self addChildViewController:tableController];
tableController.tableView = self.containerTableView;
tableController.refreshControl = self.refreshControl;
このように、UITableViewをコントローラー内にラップするだけで、[self.refreshControl endRefreshing]
はviewWillAppear
またはviewWillDisappear
内で完全に正常に機能します。場合によっては、両方で呼び出す必要があります。
お役に立てれば! :)
ナビゲーションが発生する前にendRefreshingの呼び出しを機能させることができなかったので、もう一方の端から問題にアプローチし、viewWillAppearでtableView contentOffsetが負の数であるかどうかを確認し、tableViewを0に戻します。
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.tableView.contentOffset.y < 0)
{
[self.tableView setContentOffset:CGPointZero animated:YES];
}
}
この答え 質問 私の問題を解決しました
基本的に、viewWillAppearでスピナーを停止して再開します
あなたが試すことができます
refreshControl.beginRefreshing()
refreshControl.endRefreshing()
viewWillAppearで、これは機能するはずです。
refreshControl.beginRefreshing(); refreshControl.endRefreshing()
-イベントを更新するためにもう1つのリクエスト/プルを送信しますrefreshControl.removeTarget(actionTarget, action: selector, for: .valueChanged)
refreshControl.endRefreshing()
refreshControl.beginRefreshing()
refreshControl.addTarget(actionTarget, action: actionSelector, for: .valueChanged)
私はいくつかのポイントが必要で、アルバートの解決策は好きですが、彼のスタイルは好きではありません。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_table.contentOffset = CGPointMake(_table.contentOffset.x, _table.contentOffset.y + 1.0f);
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
_table.contentOffset = CGPointMake(_table.contentOffset.x, _table.contentOffset.y - 1.0f);
}
次のコードをviewWillDisappearに配置することで、この問題を解決できました。
DispatchQueue.main.async {
self.refreshControl.beginRefreshing()
self.refreshControl.endRefreshing()
}
上記のコードをviewWillAppearに配置すると、スピナーは数秒以内にアニメーション化して閉じます。どちらの場合も問題は解決しますが、ユーザーの観点からはスピナーが表示されないようにする必要があるため、配置することをお勧めします。 viewWillDisappearでそれ。
以下のコードを追加するだけで、すべての条件で完全に機能します。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard refreshControl.isRefreshing else { return }
refreshControl.endRefreshing()
refreshControl.beginRefreshing()
tableView?.contentOffset = CGPoint(x: 0, y: -(refreshControl.bounds.height))
}
私はcollectionViewを持っていて、それをcontentInsetに設定しました。
一部のViewControllerを押してからホームボタンを押し、戻ってポップバックすると、UIRefreshControlが常に一番上に表示されます。
最後に、このコードを使用して一時的に回避します。 (醜いですが、停止すると常に一番上に表示されます)
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.refreshControl endRefreshing];
CGPoint currentContentOffset = self.collectionView.contentOffset;
[self.collectionView setContentOffset:CGPointMake(currentContentOffset.x,
currentContentOffset.y - 1.0f)
animated:YES];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
CGPoint currentContentOffset = self.collectionView.contentOffset;
[self.collectionView setContentOffset:CGPointMake(currentContentOffset.x,
currentContentOffset.y + 1.0f)
animated:YES];
}