Swift GoogleMaps fitBounds Zoom
I solved the problem by myself. I use DispatchQueue to set the right zoom to my map.
Here is my final code:
override func loadView() {
var markerList = [GMSMarker]()
// Create a GMSCameraPosition
let camera = GMSCameraPosition.camera(withLatitude: 40.4167 , longitude: -3.70325, zoom: 8)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.isMyLocationEnabled = true
view = mapView
mapView.settings.myLocationButton = true
//mapView.setMinZoom(10, maxZoom: 20)
//create markers
for loc in arrayOfMapStops {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: loc.lat, longitude: loc.long)
marker.title = loc.address
marker.snippet = loc.type
if loc.type == "Entrega" {marker.icon = GMSMarker.markerImage(with: .green)}
else {marker.icon = GMSMarker.markerImage(with: .blue)}
marker.map = mapView
markerList.append(marker)
}
delay(seconds: 3) { () -> () in
//fit map to markers
var bounds = GMSCoordinateBounds()
for marker in markerList {
bounds = bounds.includingCoordinate(marker.position)
}
let update = GMSCameraUpdate.fit(bounds, withPadding: 100.0)
mapView.animate(with: update)
}
}
func delay(seconds: Double, completion:@escaping ()->()) {
let when = DispatchTime.now() + seconds
DispatchQueue.main.asyncAfter(deadline: when) {
completion()
}
}
:)
How to fit bounds for coordinate array with google maps sdk for iOS?
Here's my solution for this problem. Building a GMSCoordinateBounds
object by multiple coordinates.
- (void)focusMapToShowAllMarkers {
CLLocationCoordinate2D myLocation = ((GMSMarker *)_markers.firstObject).position;
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:myLocation coordinate:myLocation];
for (GMSMarker *marker in _markers)
bounds = [bounds includingCoordinate:marker.position];
[_mapView animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds withPadding:15.0f]];
}
Updated answer: Since GMSMapView
markers property is deprecated, you should save all markers in your own array.
updated swift 3 answer:
func focusMapToShowAllMarkers() {
let firstLocation = (markers.first as GMSMarker).position
var bounds = GMSCoordinateBoundsWithCoordinate(firstLocation, coordinate: firstLocation)
for marker in markers {
bounds = bounds.includingCoordinate(marker.position)
}
let update = GMSCameraUpdate.fitBounds(bounds, withPadding: CGFloat(15))
self.mapView.animate(cameraUpdate: update)
}
swift - how to fit GMSMapView (google map) to show all markers and prevent over zoom
I found a simple trick to solve the problem. You can use setMinZoom
before fit
and animate
to prevent over zoom and then setMinZoom
again to allow user zoom.
var bounds = GMSCoordinateBounds()
for location in locationArray
{
let latitude = location.valueForKey("latitude")
let longitude = location.valueForKey("longitude")
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude:latitude, longitude:longitude)
marker.map = self.mapView
bounds = bounds.includingCoordinate(marker.position)
}
mapView.setMinZoom(1, maxZoom: 15)//prevent to over zoom on fit and animate if bounds be too small
let update = GMSCameraUpdate.fit(bounds, withPadding: 50)
mapView.animate(update)
mapView.setMinZoom(1, maxZoom: 20) // allow the user zoom in more than level 15 again
Fit entire Google Map in zoom level in Swift project
You can use GMSCoordinateBounds(path:)
to fit all coordinates. But it will display a world size scale
if you update the camera right after your another update. So you can use dispatch_after
to solve the problem.
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.whiteColor();
let camera = GMSCameraPosition.cameraWithLatitude(-37.813047, longitude: -72.8561644, zoom:5)
mapView = GMSMapView.mapWithFrame(CGRectZero, camera:camera)
let marker = GMSMarker()
marker.position = camera.target
marker.snippet = "Hello World"
marker.appearAnimation = kGMSMarkerAnimationPop
marker.map = mapView
self.view = mapView
delay(seconds: 2) { () -> () in
let path = GMSMutablePath()
path.addCoordinate(CLLocationCoordinate2DMake(37.36, -122.0))
path.addCoordinate(CLLocationCoordinate2DMake(37.45, -122.0))
path.addCoordinate(CLLocationCoordinate2DMake(37.45, -122.2))
path.addCoordinate(CLLocationCoordinate2DMake(37.36, -122.2))
path.addCoordinate(CLLocationCoordinate2DMake(37.36, -122.0))
let rectangle = GMSPolyline(path: path)
rectangle.map = self.mapView
let bounds = GMSCoordinateBounds(path: path)
self.mapView!.animateWithCameraUpdate(GMSCameraUpdate.fitBounds(bounds, withPadding: 15.0))
}
}
The delay
method uses the dispatch_after
:
func delay(#seconds: Double, completion:()->()) {
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64( Double(NSEC_PER_SEC) * seconds ))
dispatch_after(popTime, dispatch_get_main_queue()) {
completion()
}
}
Related Topics
When Should I Use Anyobject Insted of Uibutton in Swift
How to Hide API Keys in Github for iOS (Swift) Projects
Determine If Mkmapview Was Dragged/Moved in Swift 2.0
How to Read Heart Rate from iOS Healthkit App Using Swift
Share Attachment from Mail App with Share Extension in iOS
Swift 4 Get Error Code from Error
How to Rotate a Scnsphere Using a Pan Gesture Recognizer
Didbegincontact Passed Pkphyicsobject
Random Image for Launch Screen
Swiftui How Add Custom Modifier with Callback
Xcode6/Swift: Unrecognized Selector Sent to Instance
How to Handle Oauth-Style Log Ins with Imessage Apps in iOS 10, Xcode 8
Swift, Parse.Com: How to Pass Data from Query
How to Keep the Header Cell Moving with the Tableview Cells in Swift 2.0
How to Run a Task in Swift on a Particular Date-Time in Background Either Application Is on or Off