What is the difference between default view and UIView? - ios

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
}
}

Related

Do I really have to addSubView for each child of a UIView?

I have a Mapbox view which I'm setting up then adding as a subview. I thought it reasonable to expect that the child of that view would also be added when the Mapbox view is added. However, it seems that I need to call addSubView for each child of the first view.
Here's the entirety of my ViewController.swift:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var locationButton: UIButton!
#IBOutlet weak var buttonView: UIView!
#IBOutlet var mapView: MGLMapView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "mapbox://styles/billofbong/xxx/draft")
mapView = MGLMapView(frame: view.bounds, styleURL: url);
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.setCenter(CLLocationCoordinate2D(latitude: xxx, longitude: -xxx), zoomLevel: 15, animated: false)
mapView.showsUserLocation = true
mapView.showsHeading = true;
view.addSubview(mapView)
view.addSubview(buttonView)
}
#IBAction func onLocationButtonPressed(_ sender: Any) {
mapView.userTrackingMode = .followWithHeading
}
}
The reason I'm adding the Mapbox view as a subview instead of just having it be the original view in the ViewController is that changing the parameters didn't seem to do anything when it was the active view so I was stuck with the default map parameters.
Here's a screenshot of my storyboard:
Can anyone shed some light on the addSubView situation? What if I have a bunch of buttons? Do I really have to programmatically add each one? What am I doing wrong?
I deleted my ViewController, added a new one, linked all the IBOutlets, and now it works fine. I must have messed something up with the first ViewController.
Yes, you do have to add each button to your view. How should XCode figure out on itself where these elements should be located otherwise?

Mapbox iOS SDK use multiple files

I wanted to code a map app for personal use (iOS) using swift 5. I have already been able to make it working by using a single file, but the code looks like a mess, so I decided to use multiple files and just call functions from the ViewController.
For a simple map view I already made it possible with this code:
//ViewController.swift
import UIKit
import Mapbox
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
mapInit()
// Do any additional setup after loading the view.
}
}
//mapInit.swift
import Foundation
import Mapbox
extension ViewController{
func mapInit(){
let mapView = MGLMapView(frame: view.bounds)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Set the map’s center coordinate and zoom level.
mapView.setCenter(CLLocationCoordinate2D(latitude: 59.31, longitude: 18.06), zoomLevel: 9, animated: false)
view.addSubview(mapView)
}
}
but I tried to change the map style from the ViewController file using
mapView.styleURL = MGLStyle.darkStyleURL
but I got
Use of unresolved identifier mapView
I also tried to use
self.mapView.styleURL = MGLStyle.darkStyleURL
but now I got
Value of type 'ViewController' has no member 'mapView'
I also tried to add
var mapView: MGLMapView!
at the top of the ViewController
but now it crashes with the message
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Finally I tried to initialize the mapView from the ViewController.swift and change the style from the mapInit() but it changed nothing.
Does anyone know how to solve this problem?
If you add this
import Mapbox
import UIKit
class ViewController: UIViewController, MGLMapViewDelegate {
var mapView: MGLMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView = MGLMapView(frame: view.bounds)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.setCenter(CLLocationCoordinate2D(latitude: 0, longitude: 0), zoomLevel: 5, animated: false)
mapView.delegate = self
view.addSubview(mapView)
to your main ViewController, then you can access the mapview via an extension ViewController.

Could not cast value of type 'MKMapView' to 'MKOverlay'

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)

Google Maps API IOS cannot load new coordinates with custom UIView

I have a problem with loading coordinates for a custom UIView that has been linked through IBOutlet and subclassed as GMSMapView. The mapView loads but it always shows the wrong location every time (always London as I presume that is the default). But if I change self.mapView to self.view, the coordinates load correctly within the map. I have no clue why loading coordinates with a custom UIView doesn't work while using the superview works. Thank you in advanced!
#IBOutlet var mapView: GMSMapView!
override func loadView() {
super.loadView()
let kCameraLatitude = 37.314617900000002
let kCameraLongitude = -121.7901318
let camera = GMSCameraPosition.cameraWithLatitude(kCameraLatitude,
longitude: kCameraLongitude, zoom: 1)
let newMapView = GMSMapView.mapWithFrame(self.mapView.frame, camera: camera)
self.mapView = newMapView
}
I had the same problem.
I fixed it by changing the view camera only as such:
#IBOutlet var mapView: GMSMapView!
override func loadView() {
super.loadView()
let kCameraLatitude = 37.314617900000002
let kCameraLongitude = -121.7901318
let camera = GMSCameraPosition.cameraWithLatitude(kCameraLatitude,
longitude: kCameraLongitude, zoom: 1)
self.mapView.camera = camera
}

MapBox iOS SDK: add map event

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.

Resources