onMapTap called after onPointAnnotationClick on iOS
Hi!
In our project we have functionality when you tapping on annotation it's state set to selected, and when you tap outside of annotation on map it unselects it.
The problem is that on iOS after onPointAnnotationClick triggered and finished processing next triggered onMapTapListener that ruins our logic.
Please note that on Android this problem assumably have been solved by this PR natively.
Also I provide debug of iOS native swift code and there are to method channels called one after another (one for point annotation tap, second is map tap).
So question is it possible to harmonise solutions for both platforms and use the same approach as used in Android?
See code example:
import 'package:flutter/services.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MapboxMap(),
);
}
}
class MapboxMap extends StatefulWidget {
const MapboxMap({super.key});
@override
State<MapboxMap> createState() => _MapboxMapState();
}
class _MapboxMapState extends State<MapboxMap> {
@override
Widget build(BuildContext context) {
String accessToken = const String.fromEnvironment("PUBLIC_ACCESS_TOKEN");
var position = Position(-92.9, 35.04);
return Scaffold(
body: MapWidget(
key: const ValueKey("mapWidget"),
cameraOptions: CameraOptions(
center: Point(coordinates: position).toJson(),
zoom: 12.0,
),
resourceOptions: ResourceOptions(accessToken: accessToken),
onMapCreated: (controller) async {
final ByteData bytes =
await rootBundle.load('assets/symbols/custom-icon.png');
final Uint8List list = bytes.buffer.asUint8List();
controller.annotations
.createPointAnnotationManager()
.then((annotationManager) {
annotationManager.addOnPointAnnotationClickListener(
_AnnotationClickListener(
(annotation) {
print('Tapped on annotation at ${annotation.geometry}');
},
),
);
annotationManager.create(
PointAnnotationOptions(
geometry: Point(coordinates: position).toJson(),
image: list,
),
);
});
controller.setOnMapTapListener(
(coordinate) {
print(
'onMapTapListener fired at coordinates:[${coordinate.y},${coordinate.x}]');
},
);
},
),
);
}
}
class _AnnotationClickListener extends OnPointAnnotationClickListener {
final void Function(PointAnnotation annotation) _callback;
_AnnotationClickListener(this._callback);
@override
void onPointAnnotationClick(PointAnnotation annotation) {
_callback(annotation);
}
}
Result output:
Hi @dko-orion, thank you for writing in. I have confirmed that this is an issue on our side, I have created an internal ticket https://mapbox.atlassian.net/browse/MAPSFLT-192 to track the progress.
Any workarounds in the meantime?
Edit: The workaround for me was to implement a buffer that selects one tap event out of multiple that happen at the same time.
Hey @maios is there any update on this issue? It is currently blocking us using this official plugin.
Hey @maios is there any update on this issue? It is currently blocking us using this official plugin.
I don't know what your requirements are but if it's just recognizing annotation tap then it's quite easy to work around and should not block you. Use a StreamController and buffer your events - select only the one that you need at a time.