displaying google map within a UIView - swift3

I am using google maps with iOS.
this is my code:
class ViewController: UIViewController {
#IBOutlet weak var myMapView: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Create a GMSCameraPosition that tells the map to display the
// coordinate -33.86,151.20 at zoom level 6.
let camera = GMSCameraPosition.camera(withLatitude: +31.75097946, longitude: +35.23694368, zoom: 17.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.isMyLocationEnabled = true
mapView.mapType = .terrain
self.view = mapView
// Creates a marker in the center of the map.
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: +31.75097946, longitude: +35.23694368)
marker.title = "my location"
marker.map = mapView
}
How would i get the map to be attached to myMapView UIView?
Is there a way for the marker title to appear always?
thanks

To place a google map inside a UIView, then you need to drag a UIView object onto your canvas and subclass it as GMSMapView then create an outlet to it in your code - then you can use the following code to initialise it:
#IBOutlet weak var miniview: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
let camera = GMSCameraPosition.camera(withLatitude: +31.75097946, longitude: +35.23694368, zoom: 6.0)
miniview.camera = camera
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: +31.75097946, longitude: +35.23694368)
marker.title = "my location"
marker.map = miniview
}

You just have to use the outlet you created.
class ViewController: UIViewController {
#IBOutlet weak var myMapView: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Create a GMSCameraPosition that tells the map to display the
// coordinate -33.86,151.20 at zoom level 6.
let camera = GMSCameraPosition.camera(withLatitude: +31.75097946, longitude: +35.23694368, zoom: 17.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.isMyLocationEnabled = true
mapView.mapType = .terrain
// CHANGE THIS
self.myMapView = mapView
// Creates a marker in the center of the map.
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: +31.75097946, longitude: +35.23694368)
marker.title = "my location"
marker.map = mapView
}

Related

Google maps SDK not working on SwiftUI app

I've followed the steps of adding a map to my iOS app and then created a struct to "bridge" between swiftUI and UIkit but for some reason when I call the struct nothing would show whatsoever.
This is my viewcontroller:
import CoreLocation
import UIKit
import GoogleMaps
class ViewController: UIViewController, CLLocationManagerDelegate{
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
GMSServices.provideAPIKey("xxx")
print("License: \n\n\(GMSServices.openSourceLicenseInfo())")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.first else {
return
}
let coordinate = location .coordinate
let camera = GMSCameraPosition.camera(withLatitude: coordinate.latitude, longitude: coordinate.longitude, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: view.frame, camera: camera)
view.addSubview(mapView)
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: -coordinate.latitude, longitude: coordinate.longitude)
marker.title = "Sydney"
marker.snippet = "Australia"
marker.map = mapView
}
}
and this is the struct created in my content view:
struct YourViewControllerView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> ViewController {
return ViewController()
}
func updateUIViewController(_ uiViewController: ViewController, context: Context) {
}
}
I've searched for similar problems but everyone else had the problem of the map not loading (marker and google logo still show), whereas in my case nothing shows on the screen at all.
Just to reiterate, my Maps SDK for iOS is enabled.
I've been trying to find a solution for a week now so help is greatly appreciated.

SwiftUI - MKMapView - Display map center coordinate in a #EnvironmentObject variable

can someone please help me with my problem?
I have a SwiftUI Project and wrote a MKMapView File. I would like to store the Center coordinates in a #EnvironmentObject variable.
Unfortunately, I can't manage to pack the center coordinates into the EnvironmentObject variable.
my code looks like this:
struct MapView: UIViewRepresentable {
#EnvironmentObject var messpunkt_manager: Messpunkt_Manager
func makeUIView(context: Context) -> MKMapView {
let map = MKMapView()
map.showsUserLocation = true // zeigt den aktuellen Standort des Users
map.delegate = context.coordinator // ermöglich die Bedienung
// shows annotations already in array
for location in messpunkt_manager.messpunkte {
let annotation = MKPointAnnotation()
annotation.title = location.title
annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
map.addAnnotation(annotation)
}
return map
}
func updateUIView(_ uiView: MKMapView, context: UIViewRepresentableContext<MapView>) {
// start coordinates
let coordinate = CLLocationCoordinate2D(latitude: messpunkt_manager.centerCoordinate.latitude, longitude: messpunkt_manager.centerCoordinate.longitude)
let span = MKCoordinateSpan(latitudeDelta: messpunkt_manager.centerZoom.latitudeDelta, longitudeDelta: messpunkt_manager.centerZoom.longitudeDelta)
let region = MKCoordinateRegion(center: coordinate, span: span)
uiView.setRegion(region, animated: true)
// Adds annotation to the map
for location in messpunkt_manager.messpunkte {
let annotation = MKPointAnnotation()
annotation.title = location.title
annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
uiView.addAnnotation(annotation)
}
if messpunkt_manager.karteAusgeaehlt == 0 {
uiView.mapType = .standard
}
if messpunkt_manager.karteAusgeaehlt == 1 {
uiView.mapType = .hybrid
}
if messpunkt_manager.karteAusgeaehlt == 2 {
uiView.mapType = .satellite
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}
the center coordinates should then be put into this #EnvironmentObject variable
#Published var position = CLLocationCoordinate2D()
thanks for your help!
And sorry for my naming. For me its easier to name the variables, functions ... in my native language German. I hope its not a big deal.
In your class Coordinator you need to set the value. Assuming your coordinator is set up like this:
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
...
}
Then you would add this function:
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
parent. messpunkt_manager.position = mapView.region
}
It is really helpful to post a Minimal Reproducible Example (MRE). As you can see, you left out an important piece

Show user coordinates SwiftUI

I have custom Map with pin on user location. When i need to show user location. I tried use CLLocationManager to show coordinates but they turns 0.0
struct MapView : UIViewRepresentable {
func makeCoordinator() -> MapView.Coordinator {
return MapView.Coordinator(parent1: self)
}
#Binding var title : String
#Binding var subtitle : String
func makeUIView(context: UIViewRepresentableContext<MapView>) -> MKMapView {
let map = MKMapView()
let coordinate = CLLocationCoordinate2D(latitude: 55.757485,
longitude: 37.632179)
map.region = MKCoordinateRegion(center: coordinate,
latitudinalMeters: 100,
longitudinalMeters: 100)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
map.delegate = context.coordinator
map.addAnnotation(annotation)
return map
}
func updateUIView(_ uiView: MKMapView, context: UIViewRepresentableContext<MapView>) {}
class Coordinator: NSObject , MKMapViewDelegate {
var parent : MapView
init(parent1: MapView) {
parent = parent1
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let pin = MKPinAnnotationView(annotation: annotation,
reuseIdentifier: "pin")
pin.isDraggable = true
pin.pinTintColor = .blue
pin.animatesDrop = true
return pin
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationView.DragState, fromOldState oldState: MKAnnotationView.DragState) {
CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: (view.annotation?.coordinate.latitude)!,
longitude: (view.annotation?.coordinate.longitude)!)){ (places, err) in
if err != nil {
print((err?.localizedDescription)!)
return
}
self.parent.title = (places?.first?.name ?? places?.first?.postalCode)!
self.parent.subtitle = (places?.first?.locality ?? places?.first?.country ?? "None")
}
}
}
}
There is my start point
let coordinate = CLLocationCoordinate2D(latitude: 55.757485,
longitude: 37.632179)
So i need to add user coordinates in this stroke without asking permit as i have already asked it
All you have to do is make the showsUserLocation var true.(Look at the docs)
func makeUIView(context: UIViewRepresentableContext<MapView>) -> MKMapView {
let map = MKMapView()
let coordinate = CLLocationCoordinate2D(latitude: 55.757485, longitude: 37.632179)
map.region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 100, longitudinalMeters: 100)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
// new code...
map.showsUserLocation = true
map.delegate = context.coordinator
map.addAnnotation(annotation)
return map
}
As of iOS 14 you can use the native SwiftUI Map. This might be easier to work with than bridging to UIKit

How to create multiple markers in GoogleMaps with SwiftUI?

I need to add multiple markers in my MapView. How to add multiple markers in same mapview using swiftui?
This is my code:
import SwiftUI
import UIKit
import GoogleMaps
struct MapView: UIViewRepresentable {
let coordinate: CLLocationCoordinate2D?
let marker : GMSMarker = GMSMarker()
func makeUIView(context: Self.Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: coordinate.latitude, longitude: coordinate.longitude, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
return mapView
}
func updateUIView(_ mapView: GMSMapView, context: Self.Context) {
marker.position = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
marker.title = "XYZ"
marker.snippet = "ABCD"
marker.map = mapView
}
}
Here is my sample,
struct MapView: UIViewRepresentable {
let coordinate: CLLocationCoordinate2D
let cities = [
[
"name": "Yangon",
"lat": 16.8409,
"long": 96.1735
],
[
"name": "Mandalay",
"lat": 21.9588,
"long": 96.0891
]
]
func makeUIView(context: Self.Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: coordinate.latitude, longitude: coordinate.longitude, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
return mapView
}
func updateUIView(_ mapView: GMSMapView, context: Self.Context) {
for city in cities {
let marker : GMSMarker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: city["lat"] as! CLLocationDegrees, longitude: city["long"] as! CLLocationDegrees)
marker.title = city["name"] as? String
marker.snippet = "Welcome to \(city["name"] as! String)"
marker.map = mapView
}
}
}

How to rotate CGPoint from Landscape to Portrait UIImage orientation?

I have a UIImageView that I draw a triangle on. Points "A" leftPost & "B" rightPost are always static and the same distance from one another. The "tip" or point "C" is determined by tapping on the UIImageView. While the image is in portrait mode, I have no problem recreating the UIImageView along with the coordinates of the tapped CGPoint.
However, I need to display the UIImage in landscape mode and represent the same triangle. How do I "rotate" my coordinates to achieve this? I am also implying that I am NOT rotating the screen from portrait and landscape. The app is always in landscape.
import UIKit
class ViewController: UIViewController {
let bezierPath = UIBezierPath()
let shapeLayer = CAShapeLayer()
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let shotGesture = UITapGestureRecognizer(target: self, action: #selector(shotOnNet))
imageView.addGestureRecognizer(shotGesture)
//Enable tapping on screen
imageView.isUserInteractionEnabled = true
}
func setupBezierPath(tip: CGPoint) {
let leftPost = CGPoint(x: 20, y: 50)
let rightPost = CGPoint(x: 100, y: 50)
bezierPath.move(to: leftPost)
bezierPath.addLine(to: rightPost)
bezierPath.addLine(to: tip)
bezierPath.close()
}
func setupShapeLayer() {
shapeLayer.path = bezierPath.cgPath
shapeLayer.fillColor = UIColor.red.cgColor
shapeLayer.lineWidth = 1.0
shapeLayer.strokeColor = UIColor.black.cgColor
}
func shotOnNet(_ sender: Any) {
let shot = (sender as! UITapGestureRecognizer).location(ofTouch: 0, in: imageView)
setupBezierPath(tip: shot)
setupShapeLayer()
imageView.layer.addSublayer(shapeLayer)
}
}