3

在我们的应用程序中,我们有一个登录ViewController A。在用户登录时,会自动调用请求导航以导航到下一个ViewController B. 但是,完成此操作后,我们希望ViewController A从堆栈中删除登录,这样用户就不能“返回”到登录视图,而是返回ViewController登录前的前一个视图。

我们考虑过在加载ViewController A时从堆栈中删除ViewController B,但是有更好的方法吗?

在我们设置的应用程序的 Android 版本中history=no(如果我没记错的话),然后它就可以工作了。

在 MonoTouch 和 MvvmCross 中是否有类似的方法来实现这一点?

4

3 回答 3

8

我最终从导航控制器中删除了不需要的视图控制器。在ViewDidDisappear()我的登录中,ViewController我执行了以下操作:

public override void ViewDidDisappear (bool animated)
{
    if (this.NavigationController != null) {
        var controllers = this.NavigationController.ViewControllers;
        var newcontrollers = new UIViewController[controllers.Length - 1];
        int index = 0;
        foreach (var item in controllers) {
            if (item != this) {
                newcontrollers [index] = item;
                index++;
            }

        }
        this.NavigationController.ViewControllers = newcontrollers;
    }
    base.ViewDidDisappear(animated);
}

这样,ViewController当从视图中删除不需要的内容时,我就可以删除它。我不完全相信这是否是正确的方法,但它工作得相当好。

于 2012-12-19T12:21:28.703 回答
1

这是一个很常见的场景......以至于我们在 MvvmCross 中包含了两种机制来允许这种情况......

  1. ClearTop所有 ViewModel 导航中可用的参数。
  2. RequestRemoveBackStep()所有 ViewModel 中调用 - 尽管目前尚未在 iOS 中实现 - 抱歉。
  3. 如果这还不够,那么第三种技术可能是使用自定义演示器来帮助您的显示逻辑。

要使用: 1.ClearTop所有 ViewModel 导航中都可用的参数。

要使用它,只需在导航时包含 ClearTop 标志。

这是一个布尔标志 - 所以要使用它只需更改:

this.RequestNavigate<ChildViewModel>(new {arg1 = val1});

this.RequestNavigate<ChildViewModel>(new {arg1 = val1}, true);

ClearBackStack对于标准的简单导航控制器演示器,这将在显示新视图之前最终调用:

    public override void ClearBackStack()
    {
        if (_masterNavigationController == null)
            return;

        _masterNavigationController.PopToRootViewController (true);
        _masterNavigationController = null;
    }

来自https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Touch/Views/Presenters/MvxTouchViewPresenter.cs

如果您没有使用标准导航控制器 - 例如,如果您有一个选项卡式、模式、弹出式或拆分视图显示,那么您将需要实现自己的演示逻辑来处理这个问题。


你不能: 2. RequestRemoveBackStep().

遗憾的是,在 iOS 的通用级别上实现这一点有点尴尬 - 所以目前该方法是:

    public bool RequestRemoveBackStep()
    {
#warning What to do with ios back stack?
        // not supported on iOS really
        return false;
    }

来自https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Touch/Views/MvxTouchViewDispatcher.cs

对不起!我对此提出了一个错误 - https://github.com/slodge/MvvmCross/issues/80


3. 你总是可以... 定制想法

如果您需要为您的 iOS 应用程序实现自定义功能,最好的方法是通过某种自定义 Presenter 逻辑来实现。

有很多方法可以做到这一点。

一个例子是:

  • 对于需要清除前一个视图的任何视图或视图模型,您可以使用[Special]属性装饰视图或视图模型
  • 在您的应用程序Show的自定义Presenter中,您可以观察该属性并在当时执行特殊行为

    public override void Show(MvxShowViewModelRequest request)
    {
        if (request.ViewModelType.GetCustomAttributes(typeof(SpecialAttribute), true).Any())
        {
            // do custom behaviour here - e.g. pop current view controller
        }
    
        base.Show(request);
    }
    

显然其他机制可能是可用的 - 在这个阶段它只是 C# 和 UIKit 代码

于 2012-12-18T14:43:34.630 回答
0

我不知道 mvvm 但你可以简单地弹出没有动画的视图控制器(AC A),然后用动画推送新的视图控制器(AC B)

从 AC A 内部:

NavigationController.PopViewControllerAnimated(false);
NavigationController.PushViewController(new ACb(), true);
于 2012-12-18T14:29:03.740 回答