Using DecelerationEnded interferes with other call

2019-07-21 00:04发布

问题:

I'm trying to use the DecelerationEnded callback in conjunction with 'Tapped' callbacks on MT.Dialog elements. I can't get the two to work at the same time.

When the DecelerationEnded callback is commented out, the 'tapped' callbacks work. When it's commented in, the 'tapped' callbacks don't get triggered anymore (whereas DecelerationEnded does).

When the DecelerationEnded call is moved above the setting of the Root, then the button 'tapped' callbacks work, but the DecelerationEnded callback doesn't. Delaying the callback setup until ViewWillAppear also doesn't fix anything.

Any solutions?

Example code:

public class TestController : DialogViewController
{
    public TestController () : base(UITableViewStyle.Plain, null, true)
    {
        // Create list of 20 buttons.
        Section s = new Section();

        for (int i = 0; i < 20; i++ )
        {
            s.Add(new StringElement("test " + i, () => {
                Console.WriteLine("Tapped"); // Tapped callback.
            }));
        }

        Root = new RootElement("Test") {s};

        // The following line causes all the "tapped" handlers to not work.
        this.TableView.DecelerationEnded += HandleDecelerationEnded;
    }

    void HandleDecelerationEnded (object sender, EventArgs e)
    {
        Console.WriteLine ("Deceleration Ended");
    }
}

回答1:

In MonoTouch you can use either the C# style of callbacks or the Objective-C style of callbacks, but they can not be mixed together:

http://docs.xamarin.com/ios/advanced_topics/api_design#Delegates

Internally the MonoTouch.Dialog library implements its features by providing a full subclass that handles all of the events. If you use the C# syntax, it replaces the built-in handler with a proxy that in this case, merely responds to DecelerationEnded.

If you want to hook up to this, you need to subclass the existing "Source" class, and create this by overriding the CreateSizingSource, and it should provide a new instance of your class. This is the virtual method that you need to override to provide the same behavior but with your own classes:

public virtual Source CreateSizingSource (bool unevenRows)
{
    return unevenRows ? new SizingSource (this) : new Source (this);
}

You can just subclass SizingSource and override the method there for the deceleration method.

TweetStation has a sample that shows how this is done: it uses the same event to determine when to remove the number of unread tweets from the screen.