簡體   English   中英

為什么 PresentViewControllerAsync 不阻塞?

[英]Why doesn't PresentViewControllerAsync block?

代碼:

await vc.PresentViewControllerAsync(otherVC, true);
someMethod();

我希望這會等到呈現的otherVC退出。 這就是為什么非異步版本的最后一個參數丟失的原因,對吧? 因為它應該是someMethod 但實際上,上面的代碼只是顯示了otherVC並立即運行someMethod

如果它應該阻止 - 為什么還要有它? 為什么不只有PresentViewController

基於文檔(我不使用 Xamarin):

PresentViewControllerAsync將呈現一個視圖 controller異步- 意思是,它不會阻塞,並且下一行將在呈現otherVC執行。

PresentViewController有一個完成處理程序——意思是,otherVC 將被呈現然后完成塊將運行。 (注意,完成塊將在 VC 的呈現完成后運行......而不是在呈現的 VC 被關閉后)。

PresentViewControllerAsync是一種Asynchronous方法。 一般出現在任務方法中,最后你要回到UI線程呈現視圖controller。 如果不在任務方法中,則不需要使用它。 總之,如果你需要在任務的方法中調用當前視圖controller的UI的方法,Xamarin提供了這樣一個簡單的方法。

如果它不應該阻止 - 為什么還要有它? 為什么不只有 PresentViewController?

關於疑問,我想也許你只是想知道在哪里需要使用這個metbod。 我想說的是,在使用自定義渲染器調用原生方法時,有時會在 Xamarin Forms 中使用此方法。

例如,如果要與 Xamarin Forms 共享對話框,要激活內置的共享對話框,我們需要在每個平台上實現這個。 首先,讓我們創建一個接口,以便我們可以從我們的可移植庫中調用它。

public interface IShare
{
    Task Show(string title, string message, string filePath);
}

然后iOS將此稱為活動視圖。 創建一個 UIActivityViewController,填寫相關細節並顯示。

public class Share : IShare
{
    // MUST BE CALLED FROM THE UI THREAD
    public async Task Show(string title, string message, string filePath)
    {
        var items = new NSObject[] { NSObject.FromObject(title), NSUrl.FromFilename(filePath) };
    var activityController = new UIActivityViewController(items, null);
    var vc = GetVisibleViewController();

    NSString[] excludedActivityTypes = null;

    if (excludedActivityTypes != null && excludedActivityTypes.Length > 0)
        activityController.ExcludedActivityTypes = excludedActivityTypes;

    if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
    {
        if (activityController.PopoverPresentationController != null)
        {
            activityController.PopoverPresentationController.SourceView = vc.View;
        }
    }
    await vc.PresentViewControllerAsync(activityController, true);      
    }

    UIViewController GetVisibleViewController()
    {
        var rootController = UIApplication.SharedApplication.KeyWindow.RootViewController;

    if (rootController.PresentedViewController == null)
        return rootController;

    if (rootController.PresentedViewController is UINavigationController)
    {
        return ((UINavigationController)rootController.PresentedViewController).TopViewController;
    }

    if (rootController.PresentedViewController is UITabBarController)
    {
            return ((UITabBarController)rootController.PresentedViewController).SelectedViewController;
    }

    return rootController.PresentedViewController;
    }
}

現在在這里您可以看到 Controller 必須從 UI 任務中調用,因此需要異步方法來調用它。 這只是我對它的理解,如果以后其他人給更多的分數,那就更好了。

此外

如果想先運行present,然后運行一些方法。 也許你可以試試這個方法:

UIViewController.PresentViewController(UIViewController,Boolean,動作)

它有一個在演示結束后執行的完成操作。

使用如下:

this.PresentViewController(new UIViewController(), true, () => {
    SomeMethod();
}); 

暫無
暫無

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

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