将 DialogViewController 推送到 ViewController 到 NavigationController 堆栈会给出 2 页
Posted
技术标签:
【中文标题】将 DialogViewController 推送到 ViewController 到 NavigationController 堆栈会给出 2 页【英文标题】:Pushing a DialogViewController onto a ViewController onto NavigationController stack gives 2 pages 【发布时间】:2015-02-24 22:02:11 【问题描述】:Noob Xamarin/MonoTouch.Dialog 问题:我已经在 Xamarin Studio 的故事板设计器中布置了我的 ios 应用程序。我有一个 UINavigationController 的根视图,其中包含一个带有静态单元格的 UITableView,本质上是创建一个主菜单。这些单元格连接到它们各自的 UIViewControllers。
我想使用 MonoTouch.Dialog 布局关于/设置屏幕。但是,由于我在 Xamarin/MonoTouch.Dialog 中的新手,我遇到了一些将整体故事板方法与部分 MonoTouch.Dialogue 方法结合起来的问题
当我在与初始 UITableView (AccountViewController) 分离的 UIViewController 上实例化一个新的 DialogViewController 时,我基本上将两个视图添加到导航堆栈中,第一个仅短暂出现,然后显示 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,没有情节提要...
谢谢!
【问题讨论】:
【参考方案1】:您正在尝试将另一个 ViewController(在本例中为 DialogViewController)推送到导航堆栈,而当前的 ViewController 仍在尝试加载。换句话说,在您的 ViewDidLoad 中这样做是不好的。您必须等到当前 ViewController 完成加载并获得焦点后,才能将另一个视图控制器推送到堆栈中。
使用 Storyboard 的一部分涉及到内置的导航。我可以安全地假设您的“AccountViewController”真的没有做任何事情吗?在那种情况下,我不会继续这样做。相反,在您以前的视图控制器上,只需创建您的 DialogViewController,然后手动将其推送到堆栈上。不看你的故事板和架构就很难说。
【讨论】:
好的,谢谢。所以我想问题是:当点击/触摸 UITableViewController 中的某个静态单元格时,如何实例化 DialogViewController,然后将该 DialogViewController 推送到导航堆栈上? @Corstiaan 在您的 UITableSource(或您的 UITableViewController)中,您想要覆盖方法RowSelected()
。这是当点击或选择 UITableView 中的一行时触发的方法。查看indexPath.Row
和/或indexPath.Section
以确定选择了哪一行。从那里您可以将 DialogViewController 推送到导航堆栈上。查看有关如何使用 UITableViews 的 Xamarin 文档,这将为您提供更详细的代码示例。 Xamarin Docs for UITableViews
受您的回答启发,我解决了。明天将发布代码:-)【参考方案2】:
我通过以下方式修复它:
我为我的 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();
)
);
原来如此。不再有奇怪的空白屏幕:-)
【讨论】:
以上是关于将 DialogViewController 推送到 ViewController 到 NavigationController 堆栈会给出 2 页的主要内容,如果未能解决你的问题,请参考以下文章
永远不会调用重写的 DialogViewController 方法?
如何在 DialogViewController (Monotouch.Dialog) 上设置背景颜色
UIRefreshControl 未在 iOS 10 以下显示带有 DialogViewController 的 Xamarin
Monotouch - DialogViewController 的 TableView 背景也改变了元素的背景