【问题标题】:Wait for PresentModalViewController to finish (monotouch)等待 PresentModalViewController 完成(单点触控)
【发布时间】:2011-12-22 11:08:01
【问题描述】:

我想等待通过 PresentModalViewController() 显示的控制器完成其工作,然后再恢复执行(如 WinForms 中的模式对话框)。单点触控如何做到这一点?

我知道 SO 上有一个 similar question,但答案是针对 Objective-C 的,坦率地说,我不明白。

非常感谢。


编辑

这是我尝试的第一个设置,但似乎不起作用:

  1. 创建一个新项目(单一视图应用程序);
  2. 添加两个控制器(iPhone View Controller):FirstController和SecondController;第一个控制器覆盖 DismissModalViewControllerAnimated 并在被解除后立即触发 OnFirstFinished 事件;
  3. 在主控制器中:

...

public partial class TestModalViewController : UIViewController
{
    private UIButton button;
    private FirstController first;
    private SecondController second;

    public override void ViewDidLoad ()
    {
      base.ViewDidLoad ();

      button = UIButton.FromType(UIButtonType.RoundedRect);
      button.Frame = new RectangleF(0, 0, 100, 50);
      button.SetTitle("Test", UIControlState.Normal);
      button.TouchUpInside += PresentFirstController;

      View.Add(button);

      PresentFirstController(null, null);
    }

    void PresentFirstController (object sender, EventArgs e)
    {
      bool firstFinished = false;

      first = new FirstController();

      first.OnFirstFinished += delegate(object s, EventArgs args) {
        firstFinished = true;
      };

      this.PresentModalViewController(first, true);

      do
      {
        NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow (0.5));
      } while (!firstFinished);

      second = new SecondController();
      this.PresentModalViewController(second, true);

    }

    // ...
}
  1. 在 FirstController 中:

...

public override void DismissModalViewControllerAnimated (bool animated)
{
    base.DismissModalViewControllerAnimated (animated);

    if(null != OnFirstFinished)
    {
        OnFirstFinished(this, null);
    }
}

在此设置中,执行块(黑色加载屏幕)并且未加载第一个控制器。

如果从 ViewDidLoad() 中删除了对 PresentFirstController() 的调用,则主控制器会正常加载,并且在单击“测试”按钮时会加载第一个控制器。但是,在第一个控制器被关闭后,第二个控制器没有加载 - iOS 似乎不喜欢在关闭另一个控制器后立即呈现模态控制器。这可以通过添加一个小的延迟来解决(但多小仍然安全?),如下所示:

public override void DismissModalViewControllerAnimated (bool animated)
{
    base.DismissModalViewControllerAnimated (animated);

    NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow(0.2));

    if(null != OnFirstFinished)
    {
        OnFirstFinished(this, null);
    }
}

【问题讨论】:

    标签: ios xamarin.ios modalviewcontroller


    【解决方案1】:

    一般来说,您想在 iOS 上使用的 Code Pattern 是将这些操作链接起来。例如,您的视图控制器可能有一个登录/密码字段,以及一个用于登录的按钮。

    您要做的是将一个操作连接到与服务器联系的登录按钮,验证用户,如果凭据正常,则关闭对话框视图控制器,然后恢复执行。

    也就是说,您可以显示视图控制器并手动运行 UI 主循环,并在恢复执行之前等待某个事件触发。

    do {
        NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow (0.5));
    } while (!done);
    

    您可以为自己省点麻烦,并使用 UIKit 模式构建您的代码,而不是试图对抗它们。你最终会节省时间。

    【讨论】:

    • 感谢 Miguel,但这一次锁定就像我在等待第一个模式被解除时所做的所有其他尝试一样。我使用的代码序列是:1)创建第一个控制器并订阅自定义“OnFinished”事件; 2) PresentModalViewController() 3) 在“OnFinished”未触发时执行UI循环; 4) 为其创建第二个控制器和 PresentModalViewController()。问题是第一个控制器甚至没有显示,而执行被锁定在循环中。如果没有循环,则显示第一个模式,但不会等待控制器被关闭。
    • 实际上 Miguel 的建议确实有效,它仅在从 ViewDidLoad() 覆盖调用 PresentModal() 时才会阻塞。很快就会发布一些代码sn-ps。
    猜你喜欢
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 2021-07-14
    • 2020-04-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多