Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.5.26+3

* iOS: observe the bounds update for the `GMSMapView` to reset the camera setting.
* Update UI related e2e tests to wait for camera update on the platform thread.

## 0.5.26+2

* Fix UIKit availability warnings and CocoaPods podspec lint warnings.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,53 @@ void main() {
expect(scrollGesturesEnabled, true);
});

testWidgets('testInitialCenterLocationAtCenter', (WidgetTester tester) async {
final Completer<GoogleMapController> mapControllerCompleter =
Completer<GoogleMapController>();
final Key key = GlobalKey();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: GoogleMap(
key: key,
initialCameraPosition: _kInitialCameraPosition,
onMapCreated: (GoogleMapController controller) {
mapControllerCompleter.complete(controller);
},
),
),
);
final GoogleMapController mapController =
await mapControllerCompleter.future;

await tester.pumpAndSettle();
// TODO(cyanglaz): Remove this after we added `mapRendered` callback, and `mapControllerCompleter.complete(controller)` above should happen
// in `mapRendered`.
// https://github.com/flutter/flutter/issues/54758
await Future.delayed(Duration(seconds: 1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a reliable way to detect when it's ready?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless we add a new callback API in the google map, something like "onMapRendered". This can be in a separate PR tho.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should do that, I'm not blocking this PR since we're trading a 3 seconds timer with a 1 second one , but we should at least add a TODO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do!


ScreenCoordinate coordinate =
await mapController.getScreenCoordinate(_kInitialCameraPosition.target);
Rect rect = tester.getRect(find.byKey(key));
if (Platform.isIOS) {
// On iOS, the coordinate value from the GoogleMapSdk doesn't include the devicePixelRatio`.
// So we don't need to do the conversion like we did below for other platforms.
expect(coordinate.x, (rect.center.dx - rect.topLeft.dx).round());
expect(coordinate.y, (rect.center.dy - rect.topLeft.dy).round());
} else {
expect(
coordinate.x,
((rect.center.dx - rect.topLeft.dx) *
tester.binding.window.devicePixelRatio)
.round());
expect(
coordinate.y,
((rect.center.dy - rect.topLeft.dy) *
tester.binding.window.devicePixelRatio)
.round());
}
});

testWidgets('testGetVisibleRegion', (WidgetTester tester) async {
final Key key = GlobalKey();
final LatLngBounds zeroLatLngBounds = LatLngBounds(
Expand All @@ -401,13 +448,8 @@ void main() {
},
),
));
// We suspected a bug in the iOS Google Maps SDK caused the camera is not properly positioned at
// initialization. https://github.com/flutter/flutter/issues/24806
// This temporary workaround fix is provided while the actual fix in the Google Maps SDK is
// still being investigated.
// TODO(cyanglaz): Remove this temporary fix once the Maps SDK issue is resolved.
// https://github.com/flutter/flutter/issues/27550
await tester.pumpAndSettle(const Duration(seconds: 3));
await tester.pumpAndSettle();

final GoogleMapController mapController =
await mapControllerCompleter.future;

Expand Down Expand Up @@ -707,13 +749,11 @@ void main() {

final GoogleMapController controller = await controllerCompleter.future;

// We suspected a bug in the iOS Google Maps SDK caused the camera is not properly positioned at
// initialization. https://github.com/flutter/flutter/issues/24806
// This temporary workaround fix is provided while the actual fix in the Google Maps SDK is
// still being investigated.
// TODO(cyanglaz): Remove this temporary fix once the Maps SDK issue is resolved.
// https://github.com/flutter/flutter/issues/27550
await tester.pumpAndSettle(const Duration(seconds: 3));
await tester.pumpAndSettle();
// TODO(cyanglaz): Remove this after we added `mapRendered` callback, and `mapControllerCompleter.complete(controller)` above should happen
// in `mapRendered`.
// https://github.com/flutter/flutter/issues/54758
await Future.delayed(Duration(seconds: 1));

final LatLngBounds visibleRegion = await controller.getVisibleRegion();
final LatLng topLeft =
Expand Down Expand Up @@ -744,13 +784,11 @@ void main() {

final GoogleMapController controller = await controllerCompleter.future;

// We suspected a bug in the iOS Google Maps SDK caused the camera is not properly positioned at
// initialization. https://github.com/flutter/flutter/issues/24806
// This temporary workaround fix is provided while the actual fix in the Google Maps SDK is
// still being investigated.
// TODO(cyanglaz): Remove this temporary fix once the Maps SDK issue is resolved.
// https://github.com/flutter/flutter/issues/27550
await tester.pumpAndSettle(const Duration(seconds: 3));
await tester.pumpAndSettle();
// TODO(cyanglaz): Remove this after we added `mapRendered` callback, and `mapControllerCompleter.complete(controller)` above should happen
// in `mapRendered`.
// https://github.com/flutter/flutter/issues/54758
await Future.delayed(Duration(seconds: 1));

double zoom = await controller.getZoomLevel();
expect(zoom, _kInitialZoomLevel);
Expand Down Expand Up @@ -778,13 +816,11 @@ void main() {
));
final GoogleMapController controller = await controllerCompleter.future;

// We suspected a bug in the iOS Google Maps SDK caused the camera is not properly positioned at
// initialization. https://github.com/flutter/flutter/issues/24806
// This temporary workaround fix is provided while the actual fix in the Google Maps SDK is
// still being investigated.
// TODO(cyanglaz): Remove this temporary fix once the Maps SDK issue is resolved.
// https://github.com/flutter/flutter/issues/27550
await tester.pumpAndSettle(const Duration(seconds: 3));
await tester.pumpAndSettle();
// TODO(cyanglaz): Remove this after we added `mapRendered` callback, and `mapControllerCompleter.complete(controller)` above should happen
// in `mapRendered`.
// https://github.com/flutter/flutter/issues/54758
await Future.delayed(Duration(seconds: 1));

final LatLngBounds visibleRegion = await controller.getVisibleRegion();
final LatLng northWest = LatLng(
Expand Down Expand Up @@ -818,13 +854,11 @@ void main() {
home: Scaffold(
body: SizedBox(height: 400, width: 400, child: map)))));

// We suspected a bug in the iOS Google Maps SDK caused the camera is not properly positioned at
// initialization. https://github.com/flutter/flutter/issues/24806
// This temporary workaround fix is provided while the actual fix in the Google Maps SDK is
// still being investigated.
// TODO(cyanglaz): Remove this temporary fix once the Maps SDK issue is resolved.
// https://github.com/flutter/flutter/issues/27550
await tester.pumpAndSettle(const Duration(seconds: 3));
await tester.pumpAndSettle();
// TODO(cyanglaz): Remove this after we added `mapRendered` callback, and `mapControllerCompleter.complete(controller)` above should happen
// in `mapRendered`.
// https://github.com/flutter/flutter/issues/54758
await Future.delayed(Duration(seconds: 1));

// Simple call to make sure that the app hasn't crashed.
final LatLngBounds bounds1 = await controller.getVisibleRegion();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ @implementation FLTGoogleMapController {
FlutterMethodChannel* _channel;
BOOL _trackCameraPosition;
NSObject<FlutterPluginRegistrar>* _registrar;
// Used for the temporary workaround for a bug that the camera is not properly positioned at
// initialization. https://github.com/flutter/flutter/issues/24806
// TODO(cyanglaz): Remove this temporary fix once the Maps SDK issue is resolved.
// https://github.com/flutter/flutter/issues/27550
BOOL _cameraDidInitialSetup;
FLTMarkersController* _markersController;
FLTPolygonsController* _polygonsController;
Expand Down Expand Up @@ -119,9 +115,36 @@ - (instancetype)initWithFrame:(CGRect)frame
}

- (UIView*)view {
[_mapView addObserver:self forKeyPath:@"frame" options:0 context:nil];
return _mapView;
}

- (void)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary*)change
context:(void*)context {
if (_cameraDidInitialSetup) {
// We only observe the frame for initial setup.
[_mapView removeObserver:self forKeyPath:@"frame"];
return;
}
if (object == _mapView && [keyPath isEqualToString:@"frame"]) {
CGRect bounds = _mapView.bounds;
if (CGRectEqualToRect(bounds, CGRectZero)) {
// The workaround is to fix an issue that the camera location is not current when
// the size of the map is zero at initialization.
// So We only care about the size of the `_mapView`, ignore the frame changes when the size is
// zero.
return;
}
_cameraDidInitialSetup = YES;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not remove the observer here instead of on the next frame change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point! Thanks. will change.

[_mapView removeObserver:self forKeyPath:@"frame"];
[_mapView moveCamera:[GMSCameraUpdate setCamera:_mapView.camera]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the intended behavior if a the map frame is resized while it's being animated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, this method will get called multiple times. However, since we are always setting the camera to the same location, it shouldn't have any behavior effects.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

animateWithCameraUpdate is implemented by multiple calls to moveCamera?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this only happens once during initialization, so it shouldn't have any side effects that you worried about.

} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}

- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([call.method isEqualToString:@"map#show"]) {
[self showAtX:ToDouble(call.arguments[@"x"]) Y:ToDouble(call.arguments[@"y"])];
Expand Down Expand Up @@ -437,16 +460,6 @@ - (void)mapView:(GMSMapView*)mapView willMove:(BOOL)gesture {
}

- (void)mapView:(GMSMapView*)mapView didChangeCameraPosition:(GMSCameraPosition*)position {
if (!_cameraDidInitialSetup) {
// We suspected a bug in the iOS Google Maps SDK caused the camera is not properly positioned at
// initialization. https://github.com/flutter/flutter/issues/24806
// This temporary workaround fix is provided while the actual fix in the Google Maps SDK is
// still being investigated.
// TODO(cyanglaz): Remove this temporary fix once the Maps SDK issue is resolved.
// https://github.com/flutter/flutter/issues/27550
_cameraDidInitialSetup = YES;
[mapView moveCamera:[GMSCameraUpdate setCamera:_mapView.camera]];
}
if (_trackCameraPosition) {
[_channel invokeMethod:@"camera#onMove" arguments:@{@"position" : PositionToJson(position)}];
}
Expand Down Expand Up @@ -511,8 +524,8 @@ - (void)mapView:(GMSMapView*)mapView didLongPressAtCoordinate:(CLLocationCoordin

static NSDictionary* PointToJson(CGPoint point) {
return @{
@"x" : @((int)point.x),
@"y" : @((int)point.y),
@"x" : @(lroundf(point.x)),
@"y" : @(lroundf(point.y)),
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: google_maps_flutter
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter
version: 0.5.26+2
version: 0.5.26+3

dependencies:
flutter:
Expand Down