web-dev-qa-db-ja.com

モーダルビューコントローラーの表示の遅延

タブバーベースのアプリがあります。ルートビューコントローラーとして適切に設定されたカスタムビューコントローラーのインスタンスを持つ5つのタブすべてにナビゲーションコントローラーがあります。これは問題なくロードされます。これらのビューコントローラのいくつかには、テーブルビューが含まれています。ユーザーがテーブルビューで行を選択したときに、モーダルビューコントローラーをユーザーに表示したい。 didSelectRowAtIndexPathデリゲートメソッド(の関連部分)は次のようになります。

SampleSelectorViewController *sampleVC = [[SampleSelectorViewController alloc] init];
[self presentViewController:sampleVC animated:YES completion:NULL];

モーダルビューコントローラーが表示されますが、非常に顕著な遅延の後に表示されます。場合によっては、ユーザーが行をもう一度タップする必要があります。私がすでに確認したいくつかのことは次のとおりです。

  • ユーザーが行をタップすると、テーブルビューのdidSelectRowAtIndexPathメソッドが呼び出されます
  • DidSelectRowAtIndexPathメソッドには、ブロッキング呼び出しは含まれていません。実行中のネットワーク操作はなく、モーダルビューコントローラーの設定には、処理集約的なタスクは含まれていません。表示されるデータは静的です。
  • 新しいビューコントローラーをナビゲーションスタックにプッシュすると(他のすべてはまったく同じままです)、遅延なく完璧に動作します。遅延が発生するのは、モーダルで提示された場合のみです。

アイデア/提案はありますか?

43
Numan Tariq

presentViewController:animated:completion 内部から tableView:didSelectRowAtIndexPath:に問題があります。また、InstrumentsでTime Profilerを使用するときに目立つものを見つけるのは困難です。モーダルビューが1秒未満で表示される場合もあれば、4秒または9秒かかる場合もあります。

これは、基になるUIPresentationControllerとレイアウトに関連していると思います。これは、行をタップしてから時間プロファイラーでモーダルプレゼンテーションを表示するまでの時間の範囲を選択するときに表示される数少ないものの1つです。

この問題を説明するレーダーが存在します: http://openradar.appspot.com/19563577

回避策はシンプルですが、満足のいくものではありません。プレゼンテーションを少し遅らせて、スローダウンの原因となっている問題のある動作を回避します。

dispatch_async(dispatch_get_main_queue(), ^{
   [self presentViewController:nav animated:YES completion:nil];
});
58
azsromej

Swift 4:以下のように使用できます。

DispatchQueue.main.async {
            let popUpVc = Utilities.viewController(name: "TwoBtnPopUpViewController", onStoryboard: "Login") as? TwoBtnPopUpViewController
            self.present(popUpVc!, animated: true, completion: nil)
        }

わたしにはできる。

4
Arshad Shaik

セルのselectionStyleもUITableViewCellSelectionStyleNoneに設定していると思います。私はUITableViewCellSelectionStyleDefaultに変更し、完全に機能します。

4
Neeeeeil

ルートvcからモーダルに表示する必要があります(例:customTabBarRootViewController)。参照を保存し、参照コントローラーを使用して表示します。

3
Gilad

tableView:didSelectRowAtIndexPath:からのプレゼンテーションがAppleバグのように見える場合、この奇妙な遅延もありました。

この解決策はうまくいくようですが。

CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Fixes a bug where the main thread may be asleep, especially when using UITableViewCellSelectionStyleNone
2
trapper

ソリューションSwift

サンプルセレクターViewController(ビューコントローラーを表示したもの)では、以下のコードを使用します。

DispatchQueue.global(qos: .background).async {

// Write your code

}
1

この動作の一般的な問題は次のとおりです。

tableViewのセルにselectionStyle = .noneを設定します( http://openradar.appspotで記述されたUITableViewControllerサブクラスに依存していないようです.com/19563577 )およびデリゲートメソッドで使用

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

選択解除のアニメーション化

tableView.deselectRow(at: indexPath, animated: true)

これは、非アニメーションセルのアニメーションを意味します。

この場合、後続のビューコントローラーの表示に遅延があります。

メインスレッドにdispatch_asyncを含むいくつかの回避策がありますが、コード内の選択できないセルにアニメーションがなくてもdeselectRowを呼び出さない方がよいでしょう。

1
malex

@ Y.Bonafonsコメントに従って、Swiftでは、次のように試すことができます(for Swift 4.x&5.0)

DispatchQueue.main.async {

                self.showAction() //Show what you need to present
            }
0
iHarshil