I created a custom tile service and add it to a mapView then it works fine. then I used the same code and created a framework library with a MapView return type in Xcode 8. then I used a sample test app and import that library to it and I called the method used in library and add it to a mapView. So my problem Is when I call and that method to mapView it displays the MapKit map not my custom map
code used in library
import Foundation
import MapKit
public class mapLib: NSObject{
public class func createMap(mapView: MKMapView) ->MKMapView{
let mapView = mapView
//custom map URL
let template = "http://tile.openstreetmap.org/{z}/{x}/{y}.png"
let overlay = MKTileOverlay(urlTemplate: template)
overlay.canReplaceMapContent = true
mapView.add(overlay, level: .aboveLabels)
return mapView;
}
}
code used in app
import UIKit
import MapKit
import mapLib
class ViewController: UIViewController {
#IBOutlet weak var mapV: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
let view = mapLib.createMap(mapView: mapV)
mapV.addOverlays(view.overlays)
//any additional setup after loading the view, typically from a nib.
}
I need to clarify that the way I'm going to approach would work or any other method to do it :)
You are missing add self as delegate and implement func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer method, you can do this in your library
something like this
import Foundation
import MapKit
public class mapLib: NSObject{
public class func createMap(mapView: MKMapView) ->MKMapView{
let mapView = mapView
//custom map URL
let template = "http://tile.openstreetmap.org/{z}/{x}/{y}.png"
let overlay = MKTileOverlay(urlTemplate: template)
overlay.canReplaceMapContent = true
mapView.add(overlay, level: .aboveLabels)
mapView.delegate = self
return mapView;
}
}
extension mapLib : MKMapViewDelegate{
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let overlayTile = overlay as? MKTileOverlay{
let overLayRenderer = MKTileOverlayRenderer(tileOverlay: overlayTile)
return overLayRenderer
}
return MKOverlayRenderer(overlay: overlay)
}
}
Related
I want to set value to EnvironmentObject from Delegate class.
struct AppleMapView: UIViewRepresentable {
#EnvironmentObject var mapViewViewModel: MapViewViewModel
let mapViewDelegate = MapViewDelegate()
class MapViewDelegate: NSObject, MKMapViewDelegate {
func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) {
// This is where I want to set value to EnvObj
**mapViewViewModel.mode = mode**
}
}
}
This is what I want to do.
My code gives error
Instance member 'mapViewViewModel' of type 'AppleMapView' cannot be used on instance of nested type 'AppleMapView.MapViewDelegate'
So, I've tried giving reference to delegate class:
MapViewDelegate(vm: mapViewViewModel)
This has no compile error, but when I run the code it made errors
A View.environmentObject(_:) for MapViewViewModel may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-39.4.3/Core/EnvironmentObject.swift, line 55 ```
Neither works. How can I fix my code?
It works in different way, it needs to make your MapViewDelegate as coordinator for AppleMapView, like below
struct AppleMapView: UIViewRepresentable {
#EnvironmentObject var mapViewViewModel: MapViewViewModel
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator // << your delegate
return mapView
}
func makeCoordinator() -> MapViewDelegate {
MapViewDelegate(self) // << will be created for you
}
class MapViewDelegate: NSObject, MKMapViewDelegate {
var owner: AppleMapView
init(_ owner: AppleMapView) {
self.owner = owner
}
func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) {
owner.mapViewViewModel.mode = mode // << now you have access to owner props
}
}
}
I'm using xcode 9.0, GoogleMaps SDK 2.5.0 and GooglePlaces 2.5.0.
In the method func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool I'm trying to disable the auto center map, when I select a marker and go back to the old behaviour of only showing the marker and no auto center enabled. The problem is that the marker doesn't appear when I implement that behaviour (lines that are commented), all stack overflow I searched implements those lines. I'm lost
class MapViewController: UIViewController, GMSMapViewDelegate
{
//MARK: Class Life Cycle
#IBOutlet weak var mapView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
setupUI()
setupMap()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: -Setup
func setupUI() {
navigationController?.hideBar()
}
func setupMap() {
let map = MapManager.sharedInstance.setupMap(view: mapView, latitude: GoogleMap.latitude, longitude: GoogleMap.longitude, zoom: GoogleMap.zoom)
map.delegate = self
mapView.addSubview(map)
MapManager.sharedInstance.setupMapMarkers(map: map, file: File.geoFence, fileType: File.json)
}
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
// mapView.selectedMarker = marker
// return true
return false
}
}
If anyone comes across this odd bug, the odd solution is adding the delegate again:
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
mapView.delegate = self
mapView.selectedMarker = marker
return true
return false
}
I created a library in Xcode8 with a method used to add a map to MapKitView and I import that library to a sample project and I called the method in the library then I get an error called "Could not cast value of type 'MKMapView' (0xdc7a48) to 'MKOverlay' (0xdcca0c).
(lldb) "
the code in library
import Foundation
import MapKit
public class mapLib: NSObject{
public class func createMap(mapView: MKMapView) ->MKMapView{
let mapView = mapView
//custom map URL
let template = "http://tile.openstreetmap.org/{z}/{x}/{y}.png"
let overlay = MKTileOverlay(urlTemplate: template)
overlay.canReplaceMapContent = true
mapView.add(overlay, level: .aboveLabels)
return mapView;
}
}
the code used in the sample app
import UIKit
import MapKit
import mapLib
class ViewController: UIViewController {
#IBOutlet weak var mapV: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
let view = mapLib.createMap(mapView: mapV)
mapV.add(view as! MKOverlay) /////// Thread 1: signal SIGABRT
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I have commented the error in sample app code
MKOverlay is a protocol that MKMapView doesn't conform to by default, hence the error. Adding an MKMapView object to another MKMapView as an overlay simply cannot work, since MKMapView isn't just a simple overlay object.
If what you actually need is to add all overlays of one MKMapView to the other, you need to use below code:
let view = mapLib.createMap(mapView: mapV)
mapV.addOverlays(view.overlays)
I am using Google Map in my app. When I use self.view = map that map in a GMSMapView all is working okay.
But when I create an UIView with IBOutlet (thing with name mapView) and use to show map with markers, all the things i get is just an empty UIView.
So, what's difference is between self.view = map and self.mapView = map? What should I do?
You must use GMSMapViewDelegate and your mapView must be as GMSMapView
import GoogleMaps
class ViewController: UIViewController,GMSMapViewDelegate{
#IBOutlet weak var mapView: GMSMapView!
override func viewDidLoad() {
self.mapView.delegate = self
}
}
I'm trying to setup an iOS app with the latest MapBox iOS idk (3.2). How much i seek the internet, I can't find an example how to add a map event to the mapview.
For example: i want to add an event when the map becomes idle. Any suggestions?
UPDATE
I think this is the right method to implement:
func mapView(mapView: MGLMapView, regionDidChangeAnimated animated: Bool) {
}
If you’re asking how to use delegate methods, here’s how:
import Mapbox
// Declare conformance to the MGLMapViewDelegate protocol
class ViewController: UIViewController, MGLMapViewDelegate {
var mapView: MGLMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView = MGLMapView(frame: view.bounds)
mapView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
view.addSubview(mapView)
// Set the delegate property of our map view to self after instantiating it.
mapView.delegate = self
}
func mapView(mapView: MGLMapView, regionDidChangeAnimated animated: Bool) -> Bool {
// look at mapView properties and do something
}
}
See https://www.mapbox.com/ios-sdk/examples/ for examples of how to implement basic features with the Mapbox iOS SDK.