如何在MonoTouch中代理UIKit代表
本文关键字:代理 UIKit 代表 MonoTouch | 更新日期: 2023-09-27 17:58:24
我需要链接到UIScrollView
的委托(它不在我的代码中,我无法控制它)并处理它的一些方法,同时将所有事件传递给上一个委托。
我天真的实现是这个代理类:
public class ScrollViewProxyDelegate : UIScrollViewDelegate
{
private UIScrollViewDelegate _realDelegate;
public ScrollViewProxyDelegate (UIScrollViewDelegate realDelegate)
{
_realDelegate = realDelegate;
}
public override void DecelerationStarted (UIScrollView scrollView)
{
_realDelegate.DecelerationStarted (scrollView);
}
public override void DecelerationEnded (UIScrollView scrollView)
{
_realDelegate.DecelerationEnded (scrollView);
}
// ...
}
这没有成功,因为我传递给ScrollViewProxyDelegate
构造函数的scrollView.Delegate
原来是null
,因为这个特定的委托在不同的类树中。我想要的属性是WeakDelegate
,但它是NSObject
。
我读了这篇文章,仍然感到困惑。我想我可以在每个方法中调用NSObject
上的Objective C选择器,但可以有一种不那么详细的方法吗?
更新1
我刚刚尝试代理PerformSelector
和RespondsToSelector
,但它导致了无法识别的选择器崩溃。
更新2
好吧,显然NSProxy
就是人们用来做这个的。正在调查。
更新3
哎哟,MonoTouch中没有NSProxy
。
更新4
我最终使用KeyValueObserving来观看我的视图的contentOffset
。我应该早点考虑的!尽管如此,如果我需要的话,我还是很好奇如何实现代理
挂接到视图的代理的最简单方法是什么?
如果您尝试代理的代理为空,或者您需要代理的代理是滚动视图的WeakDelegate,我无法完全理解您对代理的需求?
WeakDelegate本质上是任何NSObject,您需要实现的任何方法都必须"导出",以便委托的所有者能够调用它们。
[Export("scrollViewDidEndDecelerating:")]
public void MyDecelerationEndedMethod(UIScrollView scrollView)
{
...
}
您可以将这样的方法添加到任何NSObject中,例如视图控制器。如果你需要使用WeakDelegate作为代理的主题,你必须查询它,看看它是否响应选择器,然后执行选择器——我认为这就是你的意思。
然而,我认为你无法编写一个可以处理任何委托的通用代理,因为尽管代理调用了RespondsToSelector,但它没有调用PerformSelector——选择器直接发送到代理,而不是通过PerformSelecter。您必须编写一个代理,该代理实现与要代理的代理完全相同的方法。
我能想到的最好的方法是如下所示,您必须实现委托实现的每个方法。
public class TestProxy : NSObject
{
private NSObject realDelegate;
public TestProxy(NSObject realDelegate)
{
this.realDelegate = realDelegate;
}
public override bool RespondsToSelector(MonoTouch.ObjCRuntime.Selector sel)
{
Console.WriteLine("Query : " + sel.Name);
return this.realDelegate.RespondsToSelector(sel);
}
[Export("tableView:didSelectRowAtIndexPath:")]
public void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
// invoke method on realDelegate either by casting to the correct type or by using
// reflection to find the method that matches the export and pass this method's arguments.
// which way you implement depends on your needs and what you know about the delegate being
// proxied - casting would be much faster than reflection.
}
}
因为您正在实现委托实现的所有方法,所以RespondsToSelector是多余的,并且不是必需的。