Xamarin iOS,在后退按钮上单击弹出多个视图控制器

时间:2017-02-28 02:08:17

标签: ios iphone xamarin.ios

如果您有四个视图控制器

A B C D

根导航控制器指向A.在视图控制器A,B和C上,有一个向右导航的按钮。这样app的流程就是

root -> A -> B -> C -> D

是否有一种方法可以让视图控制器D上的后退按钮弹出2个视图控制器并带我回到控制器B

3 个答案:

答案 0 :(得分:2)

是的,你可以这样做。

从Stack中找出要弹出的视图控制器。然后使用PopToViewController弹回到那个viewcontroller。

在D视图控制器中的后退处理程序上编写以下代码:

 this.NavigationItem.SetLeftBarButtonItem (new UIBarButtonItem(
UIImage.FromFile("back.png"), UIBarButtonItemStyle.Plain, (sender, args) => {
     var vwControllers = this.NavigationController.ViewControllers;
            foreach(UIViewController vc in vwControllers) {
                if (vc.GetType () == typeof (B)) {
                    this.NavigationController.PopToViewController (vc);
                }
}), true);

答案 1 :(得分:0)

我不知道它的Xamarine部分,但对于原生iOS应用程序,有UINavigationController方法popToViewController(_:animated:)将从堆栈弹出任意数量的视图控制器以暴露指定的查看控制器。 (那是Swift签名。Objective-C方法签名是popToViewController:animated:。)

我认为有一种方法可以从Xamarin获得该方法吗?

答案 2 :(得分:0)

虽然这可能不是理想的ui流程(你在展开控制器B时看到视图控制器3),但我得到了工作。为此,您必须在故事板文件中命名segue(必须设置每个标识符)。

如果进一步创建此链,则可以弹回2个以上的视图控制器。使用这种方法的唯一警告是ui过渡..希望这有助于其他人!

查看控制器B

public partial BViewController : UIViewController
{
    public BViewController(IntPtr handle) : base(handle)
    { }

    public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
    {
        base.PrepareForSegue(segue, sender);

        // Add to view controller stack;
        // segue Identifier (in storyboard) must match string comparison below
        if (segue.Identifier == "ToViewControllerCSegue")
        {
            var cViewController = segue.DestinationViewController as CViewController;

            if (bViewController != null)
            {
                cViewController.ViewControllerStack = new List<UIViewController>();
                cViewController.ViewControllerStack.Add(this);                   
            }
        }
    }

    // Other methods you want to have
}

查看控制器C

public partial CViewController : UIViewController
{
    public CViewController(IntPtr handle) : base(handle)
    { }

    public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
    {
        base.PrepareForSegue(segue, sender);

        // Add to view controller stack;
        // segue Identifier (in storyboard) must match string comparison below
        if (segue.Identifier == "ToViewControllerDSegue")
        {
            var dViewController = segue.DestinationViewController as DViewController;

            if (dViewController != null)
            {
                ViewControllerStack.Add(this);
                dViewController.ViewControllerStack = ViewControllerStack;
            }
        }
    }

    public List<UIViewController> ViewControllerStack { get; set; }

    // Other methods you want to have
}

查看控制器D

public partial DViewController : UIViewController
{
    public DViewController(IntPtr handle) : base(handle)
    { }

    public override void DidMoveToParentViewController(UIViewController parent)
    {
        base.DidMoveToParentViewController(parent);

        // parent will be null when clicking the back button
        if (parent == null)
        {                
            // Pops back to view controller b;
            // you could pop back further if you had more
            // viewcontrollers in the List<>
            ViewControllerStack[ViewControllerStack.Count - 1].NavigationController.PopToViewController(ViewControllerStack[0], true);

            // Refreshes view
            ReloadInputViews();
        }
    }

    public List<UIViewController> ViewControllerStack { get; set; }

    // Other methods you want to have
}