永远不会调用重写的 DialogViewController 方法?
Posted
技术标签:
【中文标题】永远不会调用重写的 DialogViewController 方法?【英文标题】:Overridden DialogViewController methods are never called? 【发布时间】:2014-02-05 14:36:32 【问题描述】:这是我的第一个问题,如果不是最好的,我很抱歉。
我是使用 Xamarin 和 ios 开发的新手。我有一个 DialogViewController 的自定义实现,以便我可以覆盖 UITableViewController 上的某些方法。为了这个问题,这是一个非常基本的实现。
public class CustomDialogViewController : DialogViewController
public CustomDialogViewController(RootElement root)
: base (root)
public override NSIndexPath WillSelectRow(UITableView tableView, NSIndexPath indexPath)
return base.WillSelectRow(tableView, indexPath);
public override NSIndexPath WillDeselectRow(UITableView tableView, NSIndexPath indexPath)
return base.WillDeselectRow(tableView, indexPath);
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
base.RowSelected(tableView, indexPath);
我这样创建我的实例:
var rootElement = new RootElement("Main");
_mainSection = new Section();
rootElement.Add(_mainSection);
dvcProductGroupList = new CustomDialogViewController(rootElement);
dvcProductGroupList.Style = UITableViewStyle.Plain;
dvcProductGroupList.TableView.Frame = new RectangleF(...);
dvcProductGroupList.View.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
dvcProductGroupList.OnSelection += dvcProductGroupList_OnSelection;
然后将 DialogViewController 添加到视图中。我在每个覆盖的开头都设置了断点,但它们永远不会被命中。在创建时没有元素,但是当视图加载时,它会用一些数据填充对话框视图控制器,4 个字符串元素。在尝试使用 MonoTouch Dialog 对行选择进行更多控制时,我将不胜感激。我试图获得取消行更改的效果,以便在单击时不会选择另一行,我认为这些是正确的方法,我只是不明白为什么它们永远不会被击中,我觉得这是一个很简单的问题。
谢谢。
【问题讨论】:
【参考方案1】:我不确定我是否以正确的方式处理这个问题,但我确实从某人那里得到了关于我在未调用被覆盖的方法时遇到的确切问题的答案,所以我会发布他们的答案以防万一有同样的问题。感谢来自 Xamarin 论坛的 JonathanBird。
您正试图在错误的类中覆盖这些方法。 DialogViewController 使用 UITableViewSource 对象来构建 UITableView。我的理解是,当使用 UiTableViewSource 配置 UITableViewController 时,不会调用 UITableViewController 中的方法。由于 DialogViewController 是 UITableViewController 的子类,这也适用于它。
DialogViewController 使用子类型 DialogViewController.Source 的 UITableViewSource 对象。如果你想覆盖有问题的方法,那么你需要继承 DialogViewController.Source 并覆盖那里的方法。
最后,您需要将 DialogViewController 创建的 DialogViewController.Source 替换为您创建的那个。您有机会通过覆盖您的 CustomDialogViewController 中的 CreateSizingSource () 来做到这一点。
DialogViewController 使用 CreateSizingSouce() 的以下实现。
public virtual DialogViewController.Source CreateSizingSource (bool unevenRows)
return (!unevenRows) ? new DialogViewController.Source (this) : new DialogViewController.SizingSource (this);
如果您的实现不使用不均匀行,那么您只需要担心返回一种类型的 Source。
例如,您的 CustomDialogViewController 中的覆盖可能是:
public override Source CreateSizingSource (bool unevenRows)
return new CustomSource(this);
CustomSource 是您的 DialogViewController.Source 的子类,它会覆盖您想要的方法。
以下是您的实现可能采用的多种可能形式之一,它显示了 RowSelected 方法的覆盖。
public class CustomDialogViewController : DialogViewController
public CustomDialogViewController (RootElement root) : base (root)
public override Source CreateSizingSource (bool unevenRows)
return new CustomSource(this);
private class CustomSource : DialogViewController.Source
public CustomSource (CustomDialogViewController controller) : base (controller)
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
// You handle row selected here
base.RowSelected (tableView, indexPath);
【讨论】:
【参考方案2】:这些方法旨在使托管 UITableViewController 符合 ObjC UITableViewDataSource
协议。然后你可以使用:
this.TableView.WeakDataSource = this;
在您的控制器中。
使用 MT.Dialog 您只处理元素,并且仅在极少数情况下处理底层UITableView
。通常你的元素有点击/点击处理程序。在其中执行您的操作。
【讨论】:
我明白你在说什么,也许我用错了方法。如果我只是对元素使用 Tapped 事件,则新元素已被选中。我试图在当前行被取消选择之前捕捉该点击并进行一些处理,并且能够不取消选择当前行并在存在条件时取消行选择,基本上保留当前选定的行而不选择新行.以上是关于永远不会调用重写的 DialogViewController 方法?的主要内容,如果未能解决你的问题,请参考以下文章
IOS:UITextInput 上的 Tokenizer 永远不会被调用