0

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);
    }

    // ...
 }

この特定のデリゲートが別のクラス ツリーにあったため、コンストラクターscrollView.Delegateに渡したことScrollViewProxyDelegateが判明したため、これはうまくいきませんでした。null私が求めているプロパティは ですがWeakDelegate、それは ですNSObject

私はこれを読んで、まだ混乱しています。各メソッドでこれに対して目的の C セレクターを呼び出すことができると思いNSObjectますが、もう少し冗長な方法はありますか?

更新 1

プロキシPerformSelectorを試してみRespondsToSelectorましたが、認識されないセレクターのクラッシュが発生しました。

更新 2

さて、どうやらNSProxy人々がこれに使用するものです。調査中。

アップデート 3

痛い、いいえNSProxy、MonoTouchでは。

更新 4

私は自分のビューを監視するために Key Value Observing を使用することになりましたcontentOffset。もっと早く考えるべきだった!それでも、必要になった場合にプロキシを実装する方法に興味があります。

ビューのデリゲートにフックする最も簡単な方法は何ですか?

4

1 に答える 1

3

プロキシしようとしているデリゲートがnullの場合、プロキシの必要性を完全に理解できませんか、それともプロキシする必要があるデリゲートがスクロールビューのWeakDelegateだったということですか?

WeakDelegate は本質的に任意の NSObject であり、デリゲートの所有者がメソッドを呼び出せるようにするには、実装する必要のあるメソッドを「エクスポート」する必要があります。

[Export("scrollViewDidEndDecelerating:")]
public void MyDecelerationEndedMethod(UIScrollView scrollView)
{
  ...
}

このようなメソッドを任意の NSObject (ビュー コントローラーなど) に追加できます。プロキシのサブジェクトとして WeakDelegate を使用する必要がある場合は、クエリを実行して、セレクターに応答するかどうかを確認し、セレクターを実行する必要があります。

ただし、プロキシは RespondsToSelector を呼び出しますが、PerformSelector を呼び出さないため、デリゲートを処理できる汎用プロキシを作成できるとは思いません。セレクターは、PerformSelector 経由ではなくプロキシに直接送信されます。 . プロキシするデリゲートとまったく同じメソッドを実装するプロキシを作成する必要があります。

私が思いつく最善の方法は、デリゲートが実装する各メソッドを実装する必要がある次のようなものです。

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 は冗長であり、必要ありません。

于 2013-02-10T06:08:10.133 に答える