Skip to content

Instantly share code, notes, and snippets.

@DelphiWorlds
Created January 29, 2021 00:40
Show Gist options
  • Save DelphiWorlds/f8b6b47565ec784006258781b6b2952b to your computer and use it in GitHub Desktop.
Save DelphiWorlds/f8b6b47565ec784006258781b6b2952b to your computer and use it in GitHub Desktop.
Show callout for map marker on iOS

Solution for showing the "callout" for a map marker on iOS

This is a relatively painless solution, however it requires patching the FMX.Maps.iOS unit as per FMX.Maps.iOS.Patch.pas in this gist.

  • Copy FMX.Maps.iOS.pas from the fmx folder in the Delphi source, and include it in the same folder as your project, or somewhere in the compiler path
  • Make the modifications to the copy as per FMX.Maps.iOS.Patch.pas in this gist
  • Include the MapsHelper.iOS.pas unit (also from this gist) with your project
  • Use the code in Unit1.pas (from this gist) as a guide as to how to show the marker's callout

Note that calling ShowCallout will show the callout for marker that was last added to the map

// Note: this is just parts of the unit to show what to "patch". Please refer to the readme.md in this gist
unit FMX.Maps.iOS;
interface
{$SCOPEDENUMS ON}
procedure RegisterMapService;
implementation
uses
MapsHelper.iOS, // <---------- Add this
System.Types, System.SysUtils, System.Generics.Collections, System.Classes, System.SyncObjs, System.Math,
System.TypInfo, System.Messaging, Macapi.ObjectiveC, Macapi.ObjCRuntime, Macapi.Helpers, iOSapi.Foundation,
iOSapi.CoreGraphics, iOSapi.UIKit, iOSapi.MapKit, iOSapi.CoreLocation, FMX.Types, FMX.Platform, FMX.Maps, FMX.Forms,
FMX.Graphics, FMX.Surfaces, FMX.Platform.iOS, FMX.Helpers.iOS, System.UITypes, FMX.MultiResBitmap, FMX.Utils,
FMX.ZOrder.iOS;
// Code snipped
procedure TMapKitMapView.InitMapView;
// Code snipped
begin
if FMapView = nil then
begin
FMapView := TMKMapView.Create;
FMapView.setHidden(True);
FDelegate := TMapKitDelegate.Create(Self);
FGestureDelegate := TMapViewGestureDelegate.Create(Self);
AddTapRecognizer(FGestureDelegate);
AddLongTapRecognizer(FGestureDelegate);
end;
SetGestureOptions;
SetControlOptions;
SetLayerOptions;
TMapsHelper.MapView := FMapView; // <---------- Add this
end;
// Code snipped
constructor TMapKitMapMarker.Create(const Descriptor: TMapMarkerDescriptor; const View: TMapKitMapView);
begin
inherited Create(Descriptor);
FView := View;
FAnnotation := TMKPointAnnotation.Wrap(TMKPointAnnotation.Alloc.init);
FAnnotation.setCoordinate(CLLocationCoordinate2D(Descriptor.Position));
FAnnotation.setTitle(StrToNSStr(Descriptor.Title));
FAnnotation.setSubtitle(StrToNSStr(Descriptor.Snippet));
TMapsHelper.Annotation := FAnnotation; // <------- Add this
end;
unit MapsHelper.iOS;
interface
uses
iOSapi.MapKit;
type
TMapsHelper = record
class var Annotation: MKPointAnnotation;
class var MapView: MKMapView;
class procedure ShowCallout; static;
end;
implementation
uses
Macapi.Helpers;
{ TMapsHelper }
class procedure TMapsHelper.ShowCallout;
begin
if (MapView <> nil) and (Annotation <> nil) then
MapView.selectAnnotation(NSObjectToID(Annotation), True);
end;
end.
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.Layouts, FMX.Maps;
type
TForm1 = class(TForm)
MapView1: TMapView;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
uses
MapsHelper.iOS;
procedure TForm1.FormShow(Sender: TObject);
begin
MapView1.Zoom := 17;
MapView1.Location := TMapCoordinate.Create(30.3976, -97.7318); // Near Embarcadero, Austin, TX
MapView1.AddMarker(TMapMarkerDescriptor.Create(MapView1.Location, 'This is an example'));
// Shows the callout for the *last* added marker
TMapsHelper.ShowCallout;
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment