簡體   English   中英

延遲呈現模式視圖控制器

[英]Delay in presenting a modal view controller

我有一個基於標簽欄的應用程序。 所有 5 個選項卡中都有導航控制器,自定義視圖控制器的實例正確設置為根視圖控制器。 這加載得很好。 其中一些視圖控制器包含表視圖。 當用戶在表視圖中選擇一行時,我想向用戶顯示一個模態視圖控制器。 didSelectRowAtIndexPath 委托方法(的相關部分)如下所示:

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

模態視圖控制器出現但它出現在一個非常明顯的延遲之后。 有時它甚至需要用戶再次點擊該行。 我已經驗證的一些事情是:

  • 當用戶點擊行時會調用表視圖的 didSelectRowAtIndexPath 方法
  • didSelectRowAtIndexPath 方法不包含任何阻塞調用。 沒有正在執行的網絡操作,模態視圖控制器的設置不涉及任何處理密集型任務。 它顯示的數據是靜態的。
  • 如果我將新的視圖控制器推送到導航堆棧上(其他所有內容都保持完全相同),它的行為將完美無缺,沒有任何延遲。 只有在模態呈現時才會遇到延遲。

任何想法/建議?

似乎從tableView:didSelectRowAtIndexPath:調用presentViewController:animated:completion是有問題的。 在 Instruments 中使用 Time Profiler 時也很難找到任何突出的東西。 有時我的模態視圖會在不到一秒的時間內出現,而其他時候則需要 4 秒甚至 9 秒。

我認為這與底層的UIPresentationController和布局有關,這是我在選擇點擊一行和在 Time Profiler 中查看模態演示之間的時間區域時看到的為數不多的事情之一。

存在描述此問題的雷達: http : //openradar.appspot.com/19563577

解決方法很簡單但並不令人滿意:稍微延遲演示以避免任何有爭議的行為導致速度變慢。

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

如果您在 tableView( :didSelectRowAt:) 中調用 present( :animated:completion:) , selectionStyle == .none 為選定的tableview 單元格並且您有這種奇怪的行為,然后嘗試調用 tableView.deselectRow(at:animated:) 之前tableView(_:didSelectRowAt:) 中的任何操作。

有幫助嗎?

Swift 4:你可以使用如下。

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

這個對我有用。

我猜您還將單元格的 selectionStyle 設置為UITableViewCellSelectionStyleNone 我更改為UITableViewCellSelectionStyleDefault並且它工作得很好。

您應該從根 vc 模態顯示它(例如:customTabBarRootViewController)。 保存一個引用,並使用引用控制器來顯示它。

當從tableView:didSelectRowAtIndexPath:看起來像一個 Apple 錯誤時,我也有這種奇怪的延遲。

不過,這個解決方案似乎效果很好。

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

Swift 3 中的解決方案

在 SampleSelectorViewController(呈現的視圖控制器)中使用以下代碼

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

// Write your code

}

這種行為的常見問題如下:

為 tableView 中的一個單元格設置selectionStyle = .none (它似乎不依賴於在http://openradar.appspot.com/19563577中編寫的UITableViewController子類化)並在委托方法中使用

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

動畫取消選擇

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

這意味着非動畫單元的動畫。

在這種情況下,后續的視圖控制器呈現會有延遲。

有一些解決方法,包括主線程上的dispatch_async ,但最好不要調用deselectRow即使代碼中不可選擇的單元格沒有動畫。

根據@Y.Bonafons 評論,在 Swift 中,您可以這樣嘗試(對於 Swift 4.x 和 5.0)

DispatchQueue.main.async {

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

試試這個 對於 swift 5.2 版,您可以使用以下代碼:

DispatchQueue.main.async(execute:{self.present(nav, animated: true)})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM