从堆栈中删除ViewController

时间:2012-12-18 14:09:05

标签: uiviewcontroller xamarin.ios stack mvvmcross

在我们的应用中,我们登录ViewController A。在用户登录时,会自动调用请求导航以导航到下一个ViewController B。但是,完成此操作后,我们要从堆栈中删除登录ViewController A,以便用户无法“返回”登录视图,但在登录前返回先前的ViewController代替。

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

在App版的Android版本中,我们设置了history=no(如果我没记错的话),然后就可以了。

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

3 个答案:

答案 0 :(得分:8)

我最终从导航控制器中删除了不需要的viewcontroller。在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时删除它。我并不完全相信它是否是正确的方法,但它的工作相当不错。

答案 1 :(得分:1)

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

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

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

    要使用它,只需在导航时包含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逻辑来实现。

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

    一个例子是:

    • 对于需要清除上一个视图的任何View或ViewModel,您可以使用[Special]属性装饰View或ViewModel
    • 在您应用中的自定义Show的{​​{1}} {li>

      中,您可以关注该属性并在当时执行特殊操作

      Presenter

    显然可能有其他机制可用 - 现阶段它只是C#和UIKit代码

答案 2 :(得分:0)

我不知道mvvm,但你可以简单地在没有动画的情况下弹出viewcontroller(AC A)然后用动画推送新的viewcontoller(AC B)

来自AC A:

NavigationController.PopViewControllerAnimated(false);
NavigationController.PushViewController(new ACb(), true);