-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
The marker info window disappears when updating the marker icon on iOS.
Even on the latest which has a fix for iOS marker not showing (without changing the marker icon though).
I'm on google_maps_flutter: ^2.12.1.
See this comment, I was discussing this bug on #159471, which is a seperate issue that is fixed. As many people were saying, there was a fix to use specific versions of google_maps_flutter and google_maps_flutter_ios, that did not resolve this issue. Contrary to what the other guy said about his code sample updating the marker icon with info window displaying, it does not display the info window.
Steps to reproduce
- Add the marker icons to "assets" with the name "selected.png" and "unselected.png"
- Run this app on iOS.
- Tap on the markers.
- Observe the info window does not show.
- Comment out this line:
// setSelectedMarker(markerId); - Tap on the markers.
- Observe the info window showing, but obviously the marker icon doesn't change.
Expected results
The info window stays open, even when the marker icon image changes.
Actual results
The info window does not show when the icon image changes. It does show when we do not update the marker icon.
Code sample
Code sample
main.dart:
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyWidget(),
);
}
}
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
List<Marker> markers = [];
GoogleMapController? googleMapController;
Marker? selectedMarker;
late BitmapDescriptor defaultPin;
late BitmapDescriptor selectedPin;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: GoogleMap(
markers: markers.toSet(),
initialCameraPosition: const CameraPosition(
target: LatLng(41.00024866867318, 29.0257125104099),
zoom: 8.4746,
),
onMapCreated: (controller) {
googleMapController = controller;
},
),
),
);
}
Future<void> getInitialMarkers() async {
defaultPin = await icon('assets/unselected.png');
selectedPin = await icon('assets/selected.png');
markers = [
Marker(
markerId: const MarkerId('1'),
position: const LatLng(40.98497470084764, 29.069472563574063),
icon: defaultPin,
infoWindow: const InfoWindow(title: 'title 1', snippet: 'snippet 1'),
onTap: () => onTap(const MarkerId('1')),
),
Marker(
markerId: const MarkerId('2'),
position: const LatLng(40.83428951050001, 29.481392650987797),
icon: defaultPin,
infoWindow: const InfoWindow(title: 'title 2', snippet: 'snippet 2'),
onTap: () => onTap(const MarkerId('2')),
),
];
refresh();
}
Future<BitmapDescriptor> icon(String path) async {
final ByteData data = await rootBundle.load(path);
final Codec codec = await instantiateImageCodec(
data.buffer.asUint8List(),
targetWidth: 100,
);
final FrameInfo frameInfo = await codec.getNextFrame();
final byteData = await frameInfo.image.toByteData(format: ImageByteFormat.png);
return BitmapDescriptor.fromBytes(byteData!.buffer.asUint8List());
}
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
getInitialMarkers();
});
}
void onTap(MarkerId markerId) {
googleMapController?.showMarkerInfoWindow(markerId);
if (selectedMarker?.markerId == markerId) {
// Deselect marker if it's already selected
setSelectedToNormal();
refresh();
return;
}
setSelectedMarker(markerId);
refresh();
}
void refresh() {
setState(() {});
}
void setSelectedMarker(MarkerId markerId) {
// Reset previously selected marker if exists
if (selectedMarker != null) {
setSelectedToNormal();
}
final markerIndex = markers.indexWhere((m) => m.markerId == markerId);
if (markerIndex != -1) {
final marker = markers[markerIndex];
markers[markerIndex] = marker.copyWith(
iconParam: selectedPin,
);
selectedMarker = markers[markerIndex];
}
}
void setSelectedToNormal() {
if (selectedMarker == null) return;
final markerIndex = markers.indexWhere((m) => m.markerId == selectedMarker!.markerId);
if (markerIndex != -1) {
final marker = markers[markerIndex];
markers[markerIndex] = marker.copyWith(
iconParam: defaultPin,
);
selectedMarker = null;
}
}
}pubspec.yaml:
name: info_window_bug
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ^3.8.0-278.1.beta
dependencies:
flutter:
sdk: flutter
google_maps_flutter: ^2.12.1
cupertino_icons: ^1.0.8
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
flutter:
uses-material-design: true
assets:
- assets/unselected.png
- assets/selected.png
AppDelegate.swift:
import UIKit
import Flutter
import GoogleMaps
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("YOUR_API_KEY_HERE")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Screenshots or Video
Screenshots / Video demonstration
When not changing marker icon:
Simulator.Screen.Recording.-.iPhone.16.-.2025-04-21.at.12.22.08.mp4
When changing marker icon:
Simulator.Screen.Recording.-.iPhone.16.-.2025-04-21.at.12.23.13.mp4
Logs
No response
Flutter Doctor output
Doctor output
[✓] Flutter (Channel beta, 3.32.0-0.1.pre, on macOS 15.3.2 24D81 darwin-arm64, locale en-GB) [371ms]
• Flutter version 3.32.0-0.1.pre on channel beta at /Users/Benji/Development/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision eeb81b9a8a (9 days ago), 2025-04-11 12:11:52 -0700
• Engine revision 72ee26e314
• Dart version 3.8.0 (build 3.8.0-278.1.beta)
• DevTools version 2.45.0
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.1) [3.3s]
• Android SDK at /Users/Benji/Library/Android/sdk
• Platform android-35, build-tools 35.0.1
• ANDROID_HOME = /Users/Benji/Library/Android/sdk
• ANDROID_SDK_ROOT = /Users/Benji/Library/Android/sdk
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
This is the JDK bundled with the latest Android Studio installation on this machine.
To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
• Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 16.3) [966ms]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 16E140
• CocoaPods version 1.16.2
[✓] Chrome - develop for the web [29ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2024.3) [29ms]
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)
[✓] IntelliJ IDEA Community Edition (version 2024.2.1) [26ms]
• IntelliJ at /Applications/IntelliJ IDEA CE.app
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
[✓] VS Code (version 1.99.1) [10ms]
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.108.0
[✓] Connected device (5 available) [6.0s]
• sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64 • Android 15 (API 35) (emulator)
• Benji’s iPhone 13 mini (wireless) (mobile) • 00008110-001119123C7B801E • ios • iOS 18.3.2 22D82
• iPhone 16 (mobile) • 8954A785-6366-40A0-BD9D-7789B1F26A1B • ios • com.apple.CoreSimulator.SimRuntime.iOS-18-4 (simulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 15.3.2 24D81 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 135.0.7049.96
[✓] Network resources [1,596ms]
• All expected network resources are available.
• No issues found!
