Ereignisse, Protokolle und Stellvertretungen in Xamarin.iOS

Xamarin.iOS verwendet Steuerelemente, um Ereignisse für die meisten Benutzerinteraktionen verfügbar zu machen. Xamarin.iOS-Anwendungen nutzen diese Ereignisse ähnlich wie herkömmliche .NET-Anwendungen. Beispielsweise verfügt die Xamarin.iOS UIButton-Klasse über ein Ereignis namens "TouchUpInside" und verwendet dieses Ereignis genauso wie diese Klasse und dieses Ereignis in einer .NET-App.

Neben diesem .NET-Ansatz macht Xamarin.iOS ein weiteres Modell verfügbar, das für komplexere Interaktion und Datenbindung verwendet werden kann. Diese Methodik verwendet, was Apple Stellvertretungen und Protokolle aufruft. Stellvertretungen ähneln dem Konzept von Delegaten in C#, aber anstatt eine einzelne Methode zu definieren und aufzurufen, ist ein Delegate in Objective-C eine ganze Klasse, die einem Protokoll entspricht. Ein Protokoll ähnelt einer Schnittstelle in C#, mit der Ausnahme, dass ihre Methoden optional sein können. Wenn Sie beispielsweise eine UITableView mit Daten auffüllen möchten, erstellen Sie eine Delegatenklasse, die die im UITableViewDataSource-Protokoll definierten Methoden implementiert, die von der UITableView aufgerufen werden, um sich selbst aufzufüllen.

In diesem Artikel erfahren Sie mehr über alle diese Themen und bieten Ihnen eine solide Grundlage für die Behandlung von Rückrufszenarien in Xamarin.iOS, einschließlich:

  • Ereignisse – Verwenden von .NET-Ereignissen mit UIKit-Steuerelementen.
  • Protokolle – Lernen Sie, welche Protokolle und wie sie verwendet werden, und erstellen Sie ein Beispiel, das Daten für eine Kartenanmerkung bereitstellt.
  • Stellvertretungen – Informationen zu Objective-C Stellvertretungen durch Erweitern des Kartenbeispiels zur Behandlung von Benutzerinteraktionen, die eine Anmerkung enthalten, und dann den Unterschied zwischen starken und schwachen Stellvertretungen und deren Verwendung zu erlernen.

Um Protokolle und Stellvertretungen zu veranschaulichen, erstellen wir eine einfache Kartenanwendung, die eine Anmerkung zu einer Karte hinzufügt, wie hier gezeigt:

Ein Beispiel für eine einfache Kartenanwendung, die einer Karte eine Anmerkung hinzufügtEiner Karte hinzugefügte Beispielanmerkung

Bevor Sie diese App angehen, beginnen wir mit .NET-Ereignissen unter dem UIKit.

.NET-Ereignisse mit UIKit

Xamarin.iOS macht .NET-Ereignisse für UIKit-Steuerelemente verfügbar. Beispielsweise verfügt UIButton über ein TouchUpInside-Ereignis, das Sie wie gewohnt in .NET behandeln, wie im folgenden Code dargestellt, der einen C#-Lambda-Ausdruck verwendet:

aButton.TouchUpInside += (o,s) => {
    Console.WriteLine("button touched");
};

Sie können dies auch mit einer anonymen C#2.0-Methode wie dieser implementieren:

aButton.TouchUpInside += delegate {
    Console.WriteLine ("button touched");
};

Der vorangehende Code wird in der ViewDidLoad Methode des UIViewController verkabelt. Die aButton Variable verweist auf eine Schaltfläche, die Sie entweder im Xcode-Schnittstellen-Generator oder mit Code hinzufügen können.

Xamarin.iOS unterstützt auch den Zielaktionsstil, den Code mit einer Interaktion zu verbinden, die mit einem Steuerelement auftritt.

Weitere Informationen zum iOS-Zielaktionsmuster finden Sie im Abschnitt "Zielaktion" der Kernkompetenzen für iOS in der iOS-Entwicklerbibliothek von Apple.

Weitere Informationen finden Sie unter Entwerfen von Benutzeroberflächen mit Xcode.

Ereignisse

Wenn Sie Ereignisse von UIControl abfangen möchten, haben Sie eine Reihe von Optionen: von der Verwendung der C#-Lambdas- und Delegatfunktionen bis hin zur Verwendung der APIs auf niedriger Ebene Objective-C .

Im folgenden Abschnitt wird gezeigt, wie Sie das TouchDown-Ereignis auf einer Schaltfläche erfassen würden, je nachdem, wie viel Steuerelement Sie benötigen.

C#-Formatvorlage

Verwenden der Stellvertretungssyntax:

UIButton button = MakeTheButton ();
button.TouchDown += delegate {
    Console.WriteLine ("Touched");
};

Wenn Sie stattdessen Lambdas mögen:

button.TouchDown += () => {
   Console.WriteLine ("Touched");
};

Wenn Sie mehrere Schaltflächen verwenden möchten, verwenden Sie denselben Handler, um denselben Code zu verwenden:

void handler (object sender, EventArgs args)
{
   if (sender == button1)
      Console.WriteLine ("button1");
   else
      Console.WriteLine ("some other button");
}

button1.TouchDown += handler;
button2.TouchDown += handler;

Überwachen mehrerer Ereignisarten

Die C#-Ereignisse für UIControlEvent-Flags weisen eine 1:1-Zuordnung zu einzelnen Flags auf. Wenn Sie zwei oder mehr Ereignisse mit demselben Codeteil behandeln möchten, verwenden Sie die UIControl.AddTarget Methode:

button.AddTarget (handler, UIControlEvent.TouchDown | UIControlEvent.TouchCancel);

Verwenden der Lambda-Syntax:

button.AddTarget ((sender, event)=> Console.WriteLine ("An event happened"), UIControlEvent.TouchDown | UIControlEvent.TouchCancel);

Wenn Sie Features Objective-Cauf niedriger Ebene verwenden müssen, z. B. das Verbinden mit einer bestimmten Objektinstanz und das Aufrufen einer bestimmten Auswahl:

[Export ("MySelector")]
void MyObjectiveCHandler ()
{
    Console.WriteLine ("Hello!");
}

// In some other place:

button.AddTarget (this, new Selector ("MySelector"), UIControlEvent.TouchDown);

Beachten Sie, dass es sich bei der Implementierung der Instanzmethode in einer geerbten Basisklasse um eine öffentliche Methode handeln muss.

Protokolle

Ein Protokoll ist ein Objective-C Sprachfeature, das eine Liste von Methodendeklarationen bereitstellt. Es dient einem ähnlichen Zweck wie eine Schnittstelle in C#, der Standard Unterschied darin, dass ein Protokoll optionale Methoden haben kann. Optionale Methoden werden nicht aufgerufen, wenn die Klasse, die ein Protokoll verwendet, diese nicht implementiert. Außerdem kann eine einzelne Klasse Objective-C mehrere Protokolle implementieren, ebenso wie eine C#-Klasse mehrere Schnittstellen implementieren kann.

Apple verwendet Protokolle in iOS, um Verträge für Klassen zu definieren, die sie übernehmen sollen, während die implementierende Klasse vom Aufrufer entfernt wird und somit genauso wie eine C#-Schnittstelle ausgeführt wird. Protokolle werden sowohl in Nichtdelegatszenarien (z. B. im MKAnnotation nächsten Beispiel) als auch mit Stellvertretungen (wie weiter unten in diesem Dokument im Abschnitt "Stellvertretungen" dargestellt) verwendet.

Protokolle mit Xamarin.ios

Sehen wir uns ein Beispiel mit einem Objective-C Protokoll aus Xamarin.iOS an. In diesem Beispiel verwenden wir das MKAnnotation Protokoll, das Teil des MapKit Frameworks ist. MKAnnotation ist ein Protokoll, mit dem jedes Objekt, das es verwendet, Informationen zu einer Anmerkung bereitzustellen, die einer Karte hinzugefügt werden kann. Beispielsweise stellt ein implementiertes MKAnnotation Objekt die Position der Anmerkung und den zugeordneten Titel bereit.

Auf diese Weise wird das MKAnnotation Protokoll verwendet, um relevante Daten bereitzustellen, die eine Anmerkung begleiten. Die tatsächliche Ansicht für die Anmerkung selbst basiert auf den Daten im Objekt, die das MKAnnotation Protokoll übernehmen. Beispielsweise stammt der Text für die Legende, die angezeigt wird, wenn der Benutzer auf die Anmerkung tippt (wie im folgenden Screenshot gezeigt), aus der Eigenschaft in der Title Klasse, die das Protokoll implementiert:

Beispieltext für die Legende, wenn der Benutzer auf die Anmerkung tippt

Wie im nächsten Abschnitt beschrieben, bindet Protocol Deep Dive, Xamarin.iOS Protokolle an abstrakte Klassen. Für das MKAnnotation Protokoll wird die gebundene C#-Klasse benannt MKAnnotation , um den Namen des Protokolls nachzuahmen, und es handelt sich um eine Unterklasse von NSObject, der Stammbasisklasse für CocoaTouch. Für das Protokoll muss ein Getter und Setter für die Koordinate implementiert werden; Ein Titel und Untertitel sind jedoch optional. Daher ist die Eigenschaft in der MKAnnotation Klasse abstrahiert und erfordert, dass sie implementiert werden muss, und die Title Eigenschaften Subtitle sind virtuell gekennzeichnet, sodass sie optional sind, wie unten dargestellt:Coordinate

[Register ("MKAnnotation"), Model ]
public abstract class MKAnnotation : NSObject
{
    public abstract CLLocationCoordinate2D Coordinate
    {
        [Export ("coordinate")]
        get;
        [Export ("setCoordinate:")]
        set;
    }

    public virtual string Title
    {
        [Export ("title")]
        get
        {
            throw new ModelNotImplementedException ();
        }
    }

    public virtual string Subtitle
    {
        [Export ("subtitle")]
        get
        {
            throw new ModelNotImplementedException ();
        }
    }
...
}

Jede Klasse kann Anmerkungsdaten bereitstellen, indem sie einfach ableiten MKAnnotation, solange mindestens die Coordinate Eigenschaft implementiert ist. Hier ist beispielsweise eine Beispielklasse, die die Koordinate im Konstruktor verwendet und eine Zeichenfolge für den Titel zurückgibt:

/// <summary>
/// Annotation class that subclasses MKAnnotation abstract class
/// MKAnnotation is bound by Xamarin.iOS to the MKAnnotation protocol
/// </summary>
public class SampleMapAnnotation : MKAnnotation
{
    string title;

    public SampleMapAnnotation (CLLocationCoordinate2D coordinate)
    {
        Coordinate = coordinate;
        title = "Sample";
    }

    public override CLLocationCoordinate2D Coordinate { get; set; }

    public override string Title {
        get {
            return title;
        }
    }
}

Über das Protokoll, an das sie gebunden ist, können alle Unterklassen MKAnnotation relevante Daten bereitstellen, die von der Karte verwendet werden, wenn sie die Ansicht der Anmerkung erstellt. Wenn Sie einer Karte eine Anmerkung hinzufügen möchten, rufen Sie einfach die AddAnnotation Methode einer MKMapView Instanz auf, wie im folgenden Code dargestellt:

//an arbitrary coordinate used for demonstration here
var sampleCoordinate =
    new CLLocationCoordinate2D (42.3467512, -71.0969456); // Boston

//create an annotation and add it to the map
map.AddAnnotation (new SampleMapAnnotation (sampleCoordinate));

Die Zuordnungsvariable hier ist eine Instanz einer MKMapView, die die Klasse darstellt, die die Karte selbst darstellt. Die MKMapView von der SampleMapAnnotation Instanz abgeleiteten Daten werden verwendetCoordinate, um die Anmerkungsansicht auf der Karte zu positionieren.

Das MKAnnotation Protokoll bietet einen bekannten Satz von Funktionen für alle Objekte, die es implementieren, ohne dass der Verbraucher (in diesem Fall die Karte) über Implementierungsdetails informiert werden muss. Dadurch wird das Hinzufügen einer Vielzahl möglicher Anmerkungen zu einer Karte optimiert.

Protokolle Deep Dive

Da C#-Schnittstellen keine optionalen Methoden unterstützen, ordnet Xamarin.iOS Protokolle abstrakten Klassen zu. Daher erfolgt die Übernahme eines Protokolls Objective-C in Xamarin.iOS durch Ableiten von der abstrakten Klasse, die an das Protokoll gebunden ist und die erforderlichen Methoden implementiert. Diese Methoden werden als abstrakte Methoden in der Klasse verfügbar gemacht. Optionale Methoden aus dem Protokoll werden an virtuelle Methoden der C#-Klasse gebunden.

Hier ist beispielsweise ein Teil des Protokolls, der UITableViewDataSource in Xamarin.iOS gebunden ist:

public abstract class UITableViewDataSource : NSObject
{
    [Export ("tableView:cellForRowAtIndexPath:")]
    public abstract UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath);
    [Export ("numberOfSectionsInTableView:")]
    public virtual int NumberOfSections (UITableView tableView){...}
...
}

Beachten Sie, dass die Klasse abstrakt ist. Xamarin.iOS macht die Klasse abstrakt, um optionale/erforderliche Methoden in Protokollen zu unterstützen. Im Gegensatz zu Objective-C Protokollen (oder C#-Schnittstellen) unterstützen C#-Klassen jedoch keine mehrfache Vererbung. Dies wirkt sich auf den Entwurf von C#-Code aus, der Protokolle verwendet, und führt in der Regel zu geschachtelten Klassen. Weitere Informationen zu diesem Problem werden weiter unten in diesem Dokument im Abschnitt "Stellvertretungen" behandelt.

GetCell(…) ist eine abstrakte Methode, die an die Objective-CSelektor gebunden ist, tableView:cellForRowAtIndexPath:die eine erforderliche Methode des UITableViewDataSource Protokolls ist. Der Selektor ist der Begriff für den Objective-C Methodennamen. Um die Methode nach Bedarf zu erzwingen, deklariert Xamarin.iOS sie als abstrakt. Die andere Methode, NumberOfSections(…)ist an .numberOfSectionsInTableview: Diese Methode ist im Protokoll optional, sodass Xamarin.iOS sie als virtuell deklariert und optional zum Überschreiben in C# macht.

Xamarin.iOS kümmert sich um alle iOS-Bindungen für Sie. Wenn Sie jedoch jemals ein Protokoll manuell Objective-C binden müssen, können Sie dies tun, indem Sie eine Klasse mit der ExportAttribute. Dies ist die gleiche Methode, die von Xamarin.iOS selbst verwendet wird.

Weitere Informationen zum Binden Objective-C von Typen in Xamarin.iOS finden Sie im Artikel "BindungstypenObjective-C".

Wir sind jedoch noch nicht mit Protokollen fertig. Sie werden auch in iOS als Grundlage für Objective-C Stellvertretungen verwendet, was das Thema des nächsten Abschnitts ist.

Delegaten

iOS verwendet Objective-C Stellvertretungen, um das Delegierungsmuster zu implementieren, in dem ein Objekt die Arbeit an eine andere übergibt. Das Objekt, das die Arbeit ausführt, ist der Delegat des ersten Objekts. Ein Objekt weist dessen Stellvertretung an, die Arbeit zu erledigen, indem er nachrichten sendet, nachdem bestimmte Dinge geschehen sind. Das Senden einer Nachricht wie dies in Objective-C ist funktional dem Aufrufen einer Methode in C# gleich. Ein Delegat implementiert Methoden als Reaktion auf diese Aufrufe und stellt daher Funktionen für die Anwendung bereit.

Mit Stellvertretungen können Sie das Verhalten von Klassen erweitern, ohne Unterklassen erstellen zu müssen. Anwendungen in iOS verwenden häufig Stellvertretungen, wenn eine Klasse nach einer wichtigen Aktion wieder zu einer anderen aufruft. Die Klasse ruft z. B. an seine Stellvertretung zurück, MKMapView wenn der Benutzer auf eine Anmerkung auf einer Karte tippt und dem Autor der Delegatenklasse die Möglichkeit gibt, innerhalb der Anwendung zu antworten. Sie können ein Beispiel für diese Art der Verwendung von Stellvertretungen weiter unten in diesem Artikel unter Verwendung eines Delegaten mit Xamarin.iOS durcharbeiten.

An diesem Punkt fragen Sie sich vielleicht, wie eine Klasse bestimmt, welche Methoden der Stellvertretung aufgerufen werden sollen. Dies ist ein weiterer Ort, an dem Sie Protokolle verwenden. In der Regel stammen die methoden, die für einen Delegat verfügbar sind, aus den von ihnen angenommenen Protokollen.

Verwendung von Protokollen mit Stellvertretungen

Wir haben bereits gesehen, wie Protokolle verwendet werden, um das Hinzufügen von Anmerkungen zu einer Karte zu unterstützen. Protokolle werden auch verwendet, um einen bekannten Satz von Methoden für Klassen bereitzustellen, die aufgerufen werden sollen, nachdem bestimmte Ereignisse auftreten, z. B. nachdem der Benutzer auf eine Anmerkung auf einer Karte tippt oder eine Zelle in einer Tabelle auswählt. Die Klassen, die diese Methoden implementieren, werden als Stellvertretungen der Klassen bezeichnet, die sie aufrufen.

Klassen, die die Delegierung unterstützen, indem sie eine Delegate-Eigenschaft verfügbar machen, der eine Klasse zugewiesen wird, die den Delegaten implementiert. Die Methoden, die Sie für den Delegaten implementieren, hängen vom Protokoll ab, das der jeweilige Delegat annimmt. Für die UITableView Methode implementieren Sie das UITableViewDelegate Protokoll für die UIAccelerometer Methode, implementieren usw. UIAccelerometerDelegatefür alle anderen Klassen in iOS, für die Sie einen Delegaten verfügbar machen möchten.

Die MKMapView Klasse, die wir in unserem früheren Beispiel gesehen haben, hat auch eine Eigenschaft namens Delegate, die aufgerufen wird, nachdem verschiedene Ereignisse auftreten. Der Delegat für MKMapView ist vom Typ MKMapViewDelegate. Sie werden dies kurz in einem Beispiel verwenden, um auf die Anmerkung zu reagieren, nachdem sie ausgewählt wurde, aber zuerst besprechen wir den Unterschied zwischen starken und schwachen Stellvertretungen.

Starke Stellvertretungen im Vergleich zu schwachen Stellvertretungen

Die Stellvertretungen, die wir bisher betrachtet haben, sind starke Stellvertretungen, was bedeutet, dass sie stark typisch sind. Die Xamarin.iOS-Bindungen werden mit einer stark typierten Klasse für jedes Delegatprotokoll in iOS geliefert. iOS hat jedoch auch das Konzept einer schwachen Stellvertretung. Anstatt eine Klasse zu unterklassigen, die an das Objective-C Protokoll für einen bestimmten Delegaten gebunden ist, können Sie auch iOS die Protokollmethoden selbst in jeder Klasse binden, die von NSObject abgeleitet ist, ihre Methoden mit dem ExportAttribute versehen und dann die entsprechenden Selektoren bereitstellen. Wenn Sie diesen Ansatz verwenden, weisen Sie der WeakDelegate-Eigenschaft anstelle der Delegate-Eigenschaft eine Instanz Ihrer Klasse zu. Eine schwache Stellvertretung bietet Ihnen die Flexibilität, Ihre Stellvertretungsklasse in eine andere Vererbungshierarchie zu übernehmen. Sehen wir uns ein Xamarin.iOS-Beispiel an, das sowohl starke als auch schwache Delegaten verwendet.

Beispiel für die Verwendung eines Delegaten mit Xamarin.iOS

Zum Ausführen von Code als Reaktion auf den Benutzer, der auf die Anmerkung in unserem Beispiel tippt, können wir eine Unterklasse unterklassen MKMapViewDelegate zuweisen und der MKMapViewEigenschaft 's Delegate ' eine Instanz zuweisen. Das MKMapViewDelegate Protokoll enthält nur optionale Methoden. Daher sind alle Methoden virtuell, die an dieses Protokoll in der Xamarin.iOS-Klasse MKMapViewDelegate gebunden sind. Wenn der Benutzer eine Anmerkung auswählt, sendet die MKMapView Instanz die mapView:didSelectAnnotationView: Nachricht an seine Stellvertretung. Um dies in Xamarin.iOS zu behandeln, müssen wir die Methode in der DidSelectAnnotationView (MKMapView mapView, MKAnnotationView annotationView) MKMapViewDelegate-Unterklasse wie folgt überschreiben:

public class SampleMapDelegate : MKMapViewDelegate
{
    public override void DidSelectAnnotationView (
        MKMapView mapView, MKAnnotationView annotationView)
    {
        var sampleAnnotation =
            annotationView.Annotation as SampleMapAnnotation;

        if (sampleAnnotation != null) {

            //demo accessing the coordinate of the selected annotation to
            //zoom in on it
            mapView.Region = MKCoordinateRegion.FromDistance(
                sampleAnnotation.Coordinate, 500, 500);

            //demo accessing the title of the selected annotation
            Console.WriteLine ("{0} was tapped", sampleAnnotation.Title);
        }
    }
}

Die oben gezeigte SampleMapDelegate-Klasse wird als geschachtelte Klasse im Controller implementiert, der die MKMapView Instanz enthält. In Objective-C, sehen Sie oft, dass der Controller mehrere Protokolle direkt innerhalb der Klasse übernimmt. Da Protokolle jedoch an Klassen in Xamarin.iOS gebunden sind, werden die Klassen, die stark typierte Delegaten implementieren, in der Regel als geschachtelte Klassen eingeschlossen.

Mit der Implementierung der Stellvertretungsklasse müssen Sie nur eine Instanz des Delegaten im Controller instanziieren und der MKMapViewEigenschaft 's Delegate zuweisen, wie hier gezeigt:

public partial class Protocols_Delegates_EventsViewController : UIViewController
{
    SampleMapDelegate _mapDelegate;
    ...
    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        //set the map's delegate
        _mapDelegate = new SampleMapDelegate ();
        map.Delegate = _mapDelegate;
        ...
    }
    class SampleMapDelegate : MKMapViewDelegate
    {
        ...
    }
}

Um eine schwache Stellvertretung zu verwenden, um dasselbe zu erreichen, müssen Sie die Methode selbst in jeder Klasse binden, von NSObject der sie abgeleitet wird, und sie der WeakDelegate Eigenschaft der .MKMapView Da die UIViewController Klasse letztendlich von NSObject (wie jeder Objective-C Klasse in CocoaTouch) abgeleitet ist, können wir einfach eine Methode implementieren, die direkt im Controller gebunden mapView:didSelectAnnotationView: ist, und den Controller MKMapViewWeakDelegatezuweisen, um die Notwendigkeit der zusätzlichen geschachtelten Klasse zu vermeiden. Der folgende Code veranschaulicht diesen Ansatz:

public partial class Protocols_Delegates_EventsViewController : UIViewController
{
    ...
    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
        //assign the controller directly to the weak delegate
        map.WeakDelegate = this;
    }
    //bind to the Objective-C selector mapView:didSelectAnnotationView:
    [Export("mapView:didSelectAnnotationView:")]
    public void DidSelectAnnotationView (MKMapView mapView,
        MKAnnotationView annotationView)
    {
        ...
    }
}

Beim Ausführen dieses Codes verhält sich die Anwendung genau so, wie sie beim Ausführen der stark typierten Stellvertretungsversion erfolgt. Der Vorteil dieses Codes besteht darin, dass der schwache Delegat nicht die Erstellung der zusätzlichen Klasse erfordert, die beim Verwenden des stark typierten Delegaten erstellt wurde. Dies kommt jedoch auf Kosten der Typsicherheit. Wenn Sie in der Auswahl einen Fehler machen würden, der an die ExportAttributeAuswahl übergeben wurde, würden Sie erst zur Laufzeit herausfinden.

Ereignisse und Stellvertretungen

Stellvertretungen werden für Rückrufe in iOS ähnlich wie bei .NET-Ereignissen verwendet. Damit iOS-APIs und die Verwendung Objective-C von Delegaten eher wie .NET aussehen, macht Xamarin.iOS .NET-Ereignisse an vielen Stellen verfügbar, an denen Stellvertretungen in iOS verwendet werden.

Beispielsweise könnte die frühere Implementierung, in der die MKMapViewDelegate antwortete Auf eine ausgewählte Anmerkung auch in Xamarin.iOS mithilfe eines .NET-Ereignisses implementiert werden kann. In diesem Fall würde das Ereignis in MKMapView und aufgerufen werden DidSelectAnnotationView. Es hätte eine EventArgs Unterklasse vom Typ MKMapViewAnnotationEventsArgs. Die View Eigenschaft würde MKMapViewAnnotationEventsArgs Ihnen einen Verweis auf die Anmerkungsansicht geben, aus der Sie mit der gleichen Implementierung fortfahren könnten, die Sie zuvor hatten, wie hier dargestellt:

map.DidSelectAnnotationView += (s,e) => {
    var sampleAnnotation = e.View.Annotation as SampleMapAnnotation;
    if (sampleAnnotation != null) {
        //demo accessing the coordinate of the selected annotation to
        //zoom in on it
        mapView.Region = MKCoordinateRegion.FromDistance (
            sampleAnnotation.Coordinate, 500, 500);

        //demo accessing the title of the selected annotation
        Console.WriteLine ("{0} was tapped", sampleAnnotation.Title);
    }
};

Zusammenfassung

In diesem Artikel wird erläutert, wie Ereignisse, Protokolle und Delegaten in Xamarin.iOS verwendet werden. Wir haben gesehen, wie Xamarin.iOS normale .NET-Stilereignisse für Steuerelemente verfügbar macht. Als Nächstes Objective-C haben wir über Protokolle erfahren, einschließlich der Unterschiede zwischen den C#-Schnittstellen und der Verwendung von Xamarin.iOS. Schließlich haben wir Stellvertretungen aus einer Xamarin.iOS-Perspektive untersucht Objective-C . Wir haben gesehen, wie Xamarin.iOS sowohl stark als auch schwach typierte Delegaten unterstützt und wie .NET-Ereignisse an Stellvertretungsmethoden gebunden werden.