将DialogViewController推送到ViewController到NavigationController堆栈上可以得到2页

时间:2015-02-24 22:02:11

标签: c# ios xamarin.ios xamarin monotouch.dialog

Noob Xamarin / MonoTouch.Dialog问题:我已经在Xamarin Studio的故事板设计器中展示了我的iOS应用程序。我有一个UINavigationController,其根视图包含带有静态单元格的UITableView,实质上是创建一个主菜单。单元格将转换为各自的UIViewControllers。

我想使用MonoTouch.Dialog布局about / settings屏幕。但是,由于我在Xamarin / MonoTouch.Dialog中的新手,我遇到了将整体故事板方法与部分MonoTouch.Dialogue方法相结合的一些问题

当我在UIViewController上实例化一个新的DialogViewController时,它从初始的UITableView(AccountViewController)中被引入,我基本上将两个视图添加到导航堆栈中,第一个只是短暂出现然后显示DialogViewController。我实例化DialogViewController的代码是:

partial class AccountViewController : UIViewController
{
    public AccountViewController (IntPtr handle) : base (handle)
    {
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
        var root = new RootElement ("Settings") {
            new Section (){
                new BooleanElement ("Airplane Mode", false),
                new RootElement ("Notifications", 0, 0) {
                    new Section (null, 
                        "Turn off Notifications to disable Sounds\n" +
                        "Alerts and Home Screen Badges for the\napplications below."){
                        new BooleanElement ("Notifications", false)
                    }
                }}
        };
        var dialog = new DialogViewController (root, true);
        this.NavigationController.PushViewController (dialog, true);
        //this.NavigationController.PresentViewController (dialog, true, null); tried this but then the UINavigationController shows no back buttons
        //View.AddSubview (dialog.View); tried this but then the UINavigationController shows no back buttons
    }   
}

我可能正在将DialogViewController推到堆栈的后期,创建中间空白屏幕,但我无法弄清楚在给定我当前架构的情况下将DialogViewController推入导航堆栈的正确位置。 互联网中的大多数样本都是近100%的MonoTouch.Dialog,没有故事板......

谢谢!

2 个答案:

答案 0 :(得分:1)

当您的当前ViewController仍在尝试加载时,您正尝试将另一个ViewController(在本例中为DialogViewController)推送到导航堆栈。换句话说,在ViewDidLoad中执行此操作很糟糕。您将不得不等到当前的ViewController完成加载并且在将另一个视图控制器推入堆栈之前获得了焦点。

使用Storyboard的一部分涉及内置的导航。我可以安全地假设你的“AccountViewController”真的没有做任何事情吗?在那种情况下,我不会进入那个阶段。而不是在以前的视图控制器上,只需创建DialogViewController,然后手动将其推入堆栈。很难说没有看你的故事板和架构。

答案 1 :(得分:1)

我通过以下方式修复它:

我为TableViewController创建了一个自定义类(包含带静态单元格的TableView):

partial class MainMenuTableViewController : UITableViewController
{
    public MainMenuTableViewController (IntPtr handle) : base (handle)
    {
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
        this.TableView.Delegate = new MainMenuTableViewDelegate (this); //this is the important part. Here I set a custom delegate class for the TableView. I pass the current TableViewController as a parameter in the constructor so I can call the NavigationController from the delegate class to push my custom MonoTouch DialogViewController onto the navigation stack
    }
}

以下是TableViewDelegate的代码:

    public class MainMenuTableViewDelegate : UITableViewDelegate
    {
        private UITableViewController _parentController;

        public MainMenuTableViewDelegate(UITableViewController parentController) : base()
        {
            _parentController = parentController;
        }

        public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
        {
            if (indexPath.Row == 2) {                   
                _parentController.NavigationController.PushViewController (new AccountDialogViewController(), true);
            }
        }
    }

我覆盖tableview委托类中的RowSelected方法,并检查当前选定的行是否等于索引2,我想要显示我的MonoTouch DialogViewController(称为AccountDialogViewController)的TableViewCell的索引。如果为true,我通过构造函数传入的父TableViewController的NavigationController属性将我的AccountDialogViewController的新实例推送到导航堆栈。

这是我的AccountDialogViewController:

public class AccountDialogViewController : DialogViewController
{
    public AccountDialogViewController () : base(new RootElement("Account settings"), true)
    {               
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
        var btnUpdatePassword = UIButton.FromType(UIButtonType.RoundedRect);
        btnUpdatePassword.SetTitle("Save new password", UIControlState.Normal);
        btnUpdatePassword.Frame = new RectangleF(0, 0, 320, 44);
        btnUpdatePassword.TouchUpInside += delegate(object sender, EventArgs e) {
            var alert = new UIAlertView("Test", "msg", null, "Cancel", null);
            alert.Show();
        };
        Root.Add(new Section ("General") {
            new EntryElement("Username", "type...", "Test"),
            new EntryElement("E-mail", "type...", "Test"),
            new RootElement ("Change password") {
                new Section (null, btnUpdatePassword) {
                    new EntryElement("New password", null, null, true),
                    new EntryElement("Confirm", null, null, true)               
                }
            },
            new StringElement ("Logout", delegate {
                var alert = new UIAlertView("Are you sure?", "Tapping Yes will log you out of your account", null, "Cancel", "Yes");
                alert.Show();
            })
        });
    }
}

所以,就是这样。没有更奇怪的空白屏幕: - )