need mapView not to updateLocation - ios

I have got mapView, and its delegate method
func mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation!) {
mapView.userTrackingMode = MKUserTrackingMode.None
var eye = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude)
var cam = MKMapCamera(lookingAtCenterCoordinate: eye, fromEyeCoordinate: eye, eyeAltitude: 10000)
UIView.animateWithDuration(1, animations: { () -> Void in
mapView.camera = cam
})
}
and it works some random way. it executes when view loads, and than when I am scrolling map to another country or city and zoom, it can(sometimes, now always) return me to my current location. It is curious cause my current location didnt changes and the delegate shouldnt execute.
I need do somehow this thing DONT HAPPENED. So i want to make my map zoom to current location only when location changed, in other way I need to have free map for scrolling.

You have to set you controller as CLLocationManagerDelegate, then declare a variable like:
var locationManager:CLLocationManager = CLLocationManager()
then in your viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.stopUpdatingLocation()
It should prevent to call func mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation!).
Pay attention that you have to re-enbale it in case you need to update map center with your coordinate without manual scrolling to you actual position.

Related

How to show recenter button only when map moves using Swift?

I'm using the default Google Map recenter button which is shown by default. How do I ensure that the recenter button is not shown by default and it's only shown when someone moves the map using Swift?
func SetupMap() {
googleMapView.settings.myLocationButton = true
}
That's pretty easy. You know how to toggle the visibility of the myLocationButton, so what's left is to think harder.
If you take time to review the GoogleMap's GMSMapViewDelegate, you will see that there are couple of methods/functions that will allow you to further your idea.
So set your mapView's delegate to your class (controller), and conform to that GMSMapViewDelegate protocol, and then implement those methods.
willMove
didChange position
These are all you need.
The willMove gets invoked when you start dragging the mapView. On the other hand, the didChange position gets called when the camera did change.
If you do these things, you'll get even nearer towards your goal. However, you might need some debounce feature in your code, because you only want to hide the location button just once, just after the user stops dragging the camera.
var debounce_timer: Timer?
extension MapsViewController: GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
print("GMS: will move")
mapView.settings.myLocationButton = true
}
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
print("GMS: didChane camera position")
debounce_timer?.invalidate()
debounce_timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { _ in
mapView.settings.myLocationButton = false
}
}
}
Voila!
Demo:

Get lat/long from the google mapview

I need to get the lat/long of the location where user taps on the google map view. Is there a necessity to open GooglePlacePickerViewController for this? I need to achieve this in the GMSMapView which is used to show user current location.
It is simple use Delegate method
First set delegate
self.mapView.delegate = self
Then just
extension YourViewController:GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
// USER TAP ON coordinate
}
}
Suggestion : Just go through this tutorial https://medium.freecodecamp.org/how-you-can-use-the-google-maps-sdk-with-ios-using-swift-4-a9bba26d9c4d will not take more than 20 min that my promise will conver all the basic stuff. :)
If you need points of view based system. for example if you want what is exact point where user tap according to view X, Y
Then
you can do it like this
let points:CGPoint = mapView.projection.point(for:coordinates)
Bingo !!
assign delegate like this.
mapView.delegate = self
And use GMSMapViewDelegate to use below method
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
print("You tapped at Location \(coordinate.latitude), \(coordinate.longitude)")
}

Mapbox iOS SDK - visibleFeaturesAtPoint returns empty array

I am trying the MGLMapView.visibleFeaturesAtPoint but am always getting back an empty array. Can someone tell me what I am doing wrong here?
Posted below is my code which is basically the adding the marker example (https://www.mapbox.com/ios-sdk/examples/marker/) but using the same point to get visible features at the marker point.
import Mapbox
class ViewController: UIViewController, MGLMapViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let mapView = MGLMapView(frame: view.bounds)
mapView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
// Set the map’s center coordinate and zoom level.
mapView.setCenterCoordinate(CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407), zoomLevel: 12, animated: false)
view.addSubview(mapView)
// Set the delegate property of our map view to `self` after instantiating it.
mapView.delegate = self
// Declare the marker `hello` and set its coordinates, title, and subtitle.
let hello = MGLPointAnnotation()
hello.coordinate = CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407)
hello.title = "Hello world!"
hello.subtitle = "Welcome to my marker"
// Add marker `hello` to the map.
mapView.addAnnotation(hello)
//let ptTest = CGPoint(x: 1, y: 1)
print(mapView.visibleCoordinateBounds)
let ptTest = mapView.convertCoordinate(hello.coordinate, toPointToView: mapView)
print(ptTest)
print(mapView.visibleFeatures(at: ptTest))
}
// Use the default marker. See also: our view annotation or custom marker examples.
func mapView(mapView: MGLMapView, viewForAnnotation annotation: MGLAnnotation) -> MGLAnnotationView? {
return nil
}
// Allow callout view to appear when an annotation is tapped.
func mapView(mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
return true
}
}
Question was answered by mapbox team on Github.
"Does the issue reproduce if you move the call to visibleFeatures(at:) to viewDidAppearAnimated(:) or mapViewDidFinishLoadingMap(:)? By the time viewDidLoad() runs, the view controller has loaded, but the map view may not have had a chance to load the style or tiles completely yet."
Apparently putting it in viewDidLoad() meant that the map had not fully loaded yet and so the features array was returned empty. Moving it to mapViewDidFinishLoadingMap() fixed the issue.

unable to scroll MKMapView.

I'm trying to do an iOS app using Xcode 6.3 and swift. I use MKMapView for tracking user position. The problem is that if I scroll the map I immediately return to the user position. This is my code:
override func viewDidLoad() {
super.viewDidLoad()
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
theMap.delegate = self
theMap.mapType = MKMapType.Standard
theMap.zoomEnabled = true
theMap.addGestureRecognizer(longPress)
theMap.scrollEnabled = true
}
and
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
let spanX = 0.007
let spanY = 0.007
var newRegion = MKCoordinateRegion(center: theMap.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))
theMap.setRegion(newRegion, animated: false)
theMap.scrollEnabled = true
}
If I scroll the map, after 1 sec I return to the user position. Should I change setRegion method position?
You need to detect when you scroll the map, possibly by implementing the mapView(_:regionWillChangeAnimated:) method defined in MKMapViewDelegate. In this method you need to set the userTrackingMode property of your map view to .None. Your implementation will be called when the user pans or zooms your theMap variable. So you should strive to keep the implementation as lightweight as possible since it could be called many times for a single pan or zoom gesture.
func mapView(mapView: MKMapView!, regionWillChangeAnimated animated: Bool) {
if you want to stop tracking the user {
mapView.userTrackingMode = .None
}
}
When you want to start following the user's location again, change that property back to either .Follow or .FollowWithHeading:
enum MKUserTrackingMode : Int {
case None // the user's location is not followed
case Follow // the map follows the user's location
case FollowWithHeading // the map follows the user's location and heading
}

Fixed marker on google maps for ios

I am using google maps SDK for ios. I want to make a marker fixed in the center of the screen, so when user drags the map, the marker does not move and stays in the center. I am also trying to read the coordinate of the center after the drag. Any input would be appreciated. Thanks!
I would rather display view on top of GMSMapView (do not use markers for that). Since you have screen position for map view, that should be easy to place your view in correct position.
To get coordinates you can use mapView.projection.coordinateForPoint
Documentation is here
To know that drag is finished, make you view controller (or any other object) delegate of map view (GMSMapViewDelegate) and implement mapView:idleAtCameraPosition: method.
Docs are here
Create outlet of GMSMapView and attached Image at the center of the map and search bar at the top to present the location name.
Drag the map on Device, which will trigger 2 delegate method of GMSMapViewDelegate.
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) 
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) 
/**
* Called repeatedly during any animations or gestures on the map (or once, if the camera is
* explicitly set). This may not be called for all intermediate camera positions. It is always
* called for the final position of an animation or gesture.
*/
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
print("didchange")> >
returnPostionOfMapView(mapView: mapView)
}
/**
* Called when the map becomes idle, after any outstanding gestures or animations have completed (or
* after the camera has been explicitly set).
*/
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
print("idleAt")
//called when the map is idle
returnPostionOfMapView(mapView: mapView)
}
//Convert the location position to address
func returnPostionOfMapView(mapView:GMSMapView){
let geocoder = GMSGeocoder()
let latitute = mapView.camera.target.latitude
let longitude = mapView.camera.target.longitude
let position = CLLocationCoordinate2DMake(latitute, longitude)
geocoder.reverseGeocodeCoordinate(position) { response , error in
if error != nil {
print("GMSReverseGeocode Error: \(String(describing: error?.localizedDescription))")
}else {
let result = response?.results()?.first
let address = result?.lines?.reduce("") { $0 == "" ? $1 : $0 + ", " + $1 }
self.searchBar.text = address
}
}
}
Github Demo Project

Resources