MKMapView cannot scroll and zoom in iOS 5.0 - ios

I run this code normally in iOS 4.3. But when I change the project to iOS 5.0, I cannot scroll and zoom the map.
Can anybody tell me why has this problem? How can I solve it?
The code is:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect rect = CGRectMake(0, 0, 320, 460);
map = [[MKMapView alloc] initWithFrame:rect];
map.showsUserLocation = YES;
MKUserLocation *userLocation = map.userLocation;
[userLocation addObserver:self forKeyPath:#"location"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
context:nil];
map.scrollEnabled = YES;
map.zoomEnabled = YES;
map.mapType = MKMapTypeStandard;
[self.view addSubview:map];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([change objectForKey:NSKeyValueChangeNewKey] != [NSNull null]) {
MKCoordinateRegion region;
CLLocationCoordinate2D testCoordinate;
double lat = 22.195579570451734;
double lng = 113.542275265336;
testCoordinate.latitude = lat;
testCoordinate.longitude = lng;
region.center = testCoordinate;
MKCoordinateSpan span;
span.latitudeDelta = 0.0011;
span.longitudeDelta = 0.0011;
region.span = span;
[map setRegion:region animated:YES];
}
}

The code is observing changes to the user location and updating the map's region to some fixed region when that happens.
In the iOS Simulator before iOS 5.0, the user location changes were not simulated and so the location change observer method would either not fire or not fire as frequently. So if you scrolled or zoomed the map, the map would stay that way until the observer method fired (probably never).
In the iOS Simulator for iOS 5.0, the user location changes are (or can be) simulated. Under the iOS Simulator's Debug menu, there is a Location sub-menu. If this is set to anything but None, the user location change event will happen and cause the observer method to fire. If the Location setting is City Bicycle Ride, City Run, or Freeway Drive, the user location will change very frequently.
Since your observer method is re-setting the map's region to some fixed area every time the user location changes, any scrolling or zooming you do to the map is almost immediately un-done.
Change the Location setting to either None or Custom Location (which will fire only once).
An un-related point is you don't need to use KVO to observe changes to the user location. Unless your app needs to run on iOS 3.0 or earlier, you should use the MKMapViewDelegate method mapView:didUpdateUserLocation: instead.

Related

Displaying current location on Google maps

I have an iOS app that uses Google Maps SDK to display a map within my app.
I have managed to get the map displaying but I dont know how to set the camera or the marker to the users current location.
I have hard coded the coordinates just to test is the map working but I am now stuck on how to display current location of the user.
Here is my code to centre the camera to a coordinate
- (void)viewDidLoad
{
[super viewDidLoad];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:47.995602 longitude:-78.902153 zoom:6];
self.mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
self.mapView.myLocationEnabled = YES;
self.mapView.mapType = kGMSTypeNormal;
self.mapView.accessibilityElementsHidden = NO;
self.mapView.settings.scrollGestures = YES;
self.mapView.settings.zoomGestures = YES;
self.mapView.settings.compassButton = YES;
self.mapView.settings.myLocationButton = YES;
self.mapView.delegate = self;
self.view = self.mapView;
[self placeMarkers];
}
And here is the code to display the marker at coordinates
-(void)placeMarkers
{
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(47.995602, -78.902153);
marker.title = #"PopUp HQ";
marker.snippet = #"Durham, NC";
marker.icon = [GMSMarker markerImageWithColor:[UIColor blueColor]];
marker.opacity = 0.9;
marker.map = self.mapView;
}
I have tried to get the current position as follows:
CLLocationCoordinate2D *myLocation = self.mapView.myLocation.coordinate;
but I get the error:
Initializing 'CLLocationCoordinate2D' with an expression of incompatible type 'CLLocationCoordinate2D'
How can I get the current location to pass to the camera as well as marker?
CLLocationCoordinate2D is just a struct containing a latitude and longitude, so you can simply use
CLLocationCoordinate2D myLocation = self.mapView.myLocation.coordinate;
It is also worth using KVO to observe changes to myLocation, as it is possible that the mapView won't yet have a valid location.
To explain further about KVO:
You can add an observer for the myLocation property as follows:
[self.mapView addObserver:self
forKeyPath:#"myLocation"
options:(NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld)
context:NULL];
You should then implement the following method:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqualToString:#"myLocation"]) {
// NSLog(#"My position changed");
}
}
You can then safely access self.mapView.myLocation.coordinate knowing that the location is valid.
Don't forget to remove yourself as an observer when the mapview is deallocated:
[self.mapView removeObserver:self forKeyPath:#"myLocation"];
As Saxon has already mentioned, the mapview will show it's own current position indicator. The marker that you are adding will be shown in addition, but it is likely that mapview doesn't yet having a valid position when you are creating the marker, so it is being added at latitude/longitude 0,0 which is in the middle of the ocean.
When you set myLocationEnabled to YES then the map automatically adds a marker at your current location. So you probably don't need to add your own?
It takes time for the device and your app to determine your location. When it starts up it probably doesn't know your location yet, so it defaults to lat/lon of zero, which is off Africa.
As NigelG said, you can use KVO on the myLocation property to find out when the position updates.

Could not get current location using Google Map API (GMSMapView)

I try to get the direction from current location to other point using Google Map API. Everything is OK when i input the origin point and destination point manually. But, when i try to set the origin point as current location, the location is null as the following code:
mainMap=[[GMSMapView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithTarget:[mainMap.myLocation coordinate] zoom:13];
mainMap.camera=camera;
mainMap.myLocationEnabled=YES; // <---- The blue point appear on map: it's exactly my location
[self.view addSubview:mainMap];
//Get mylocation
CLLocation *myLocation = mainMap.myLocation; // <----- NULL
Is there any body know what is my problem here? Tks a lot
The thing is: Getting a location is asynchronous and how you do it is expect it to block till its there... which is not how it works
you have to add a KVO observer inn the map and observer myLocation.
Then when your observe method gets called, you get the myLocation.
(that's how the blue dot works too :))
- (void)viewDidLoad {
//...
[self.mapView addObserver:self forKeyPath:"myLocation" options:0 context:nil];
}
- (void)dealloc {
[_mapView removeObserver:self forKeyPath:#"myLocation"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if([keyPath isEqualToString:#"myLocation"]) {
CLLocation *l = [object myLocation];
//...
}
}

GMSMapView myLocation not giving actual location

I have a GMSMapView properly loaded and working inside my viewcontroller
what i'm not being able to do is setting the GMSCameraPosition around my location
this is my code:
mapView_.myLocationEnabled = YES;
CLLocation* myLoc = [mapView_ myLocation];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:myLoc.coordinate.latitude
longitude:myLoc.coordinate.longitude
zoom:4];
[mapView_ setCamera:camera];
GPS is enabled and application has all needed permissions but myLocation returns a nil CLLocation, consequentially cameraWithLatitude:longitude:zoom: get 0 0 coordinates and displays Africa instead of my actual location (that is not in africa :) )
From official Google Maps iOS SDK documentation:
(BOOL) myLocationEnabled [read, write, assign]
Controls whether the My Location dot and accuracy circle is enabled.
Defaults to NO.
(CLLocation*) myLocation [read, assign]
If My Location is enabled, reveals where the user location dot is being drawn.
If it is disabled, or it is enabled but no location data is available, this will be nil. This property is observable using KVO.
So when you set mapView_.myLocationEnabled = YES;, it only tells the mapView to reveal the blue dot only if you have a location value given to the myLocation property. The sample code from Google shows how to observe the user location using the KVO method.(Recommended) You can also implement the CLLocationManagerDelegate method, to update the mapView.
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[mapView animateToLocation:newLocation.coordinate];
// some code...
}
Here are the code from google maps sample code on how to use KVO to update user location.
// in viewDidLoad method...
// Listen to the myLocation property of GMSMapView.
[mapView_ addObserver:self
forKeyPath:#"myLocation"
options:NSKeyValueObservingOptionNew
context:NULL];
// Ask for My Location data after the map has already been added to the UI.
dispatch_async(dispatch_get_main_queue(), ^{
mapView_.myLocationEnabled = YES;
});
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (!firstLocationUpdate_) {
// If the first location update has not yet been recieved, then jump to that
// location.
firstLocationUpdate_ = YES;
CLLocation *location = [change objectForKey:NSKeyValueChangeNewKey];
mapView_.camera = [GMSCameraPosition cameraWithTarget:location.coordinate
zoom:14];
}
}
Try to using MapKit, under the VieDidLoad or ViewWillApper using:
myMapView.showsUserLocation = YES;
You can add this simple code under the IBAction if you want, like a :
- (IBAction)getLocation:(id)sender{
myMapView.showsUserLocation = YES;
}
I hope this help you

iOS Mapkit - User location shown as 0, 0

So I am building a location based game and have a problem getting a users location to initialize properly.
It doesn't always happen, but sometimes the location never changes from 0,0.
This causes a problem as I have a loading view (vault) that blocks the map from being displayed until the player's location is loaded and not 0,0. So if the user location doesnt get set, the vault never opens showing the map.
Is there any other way to ensure the user location is loaded?
FYI - I already ensure they have location services enabled and their device is capable.
I am having this issue on and off on my own devices with everything enabled properly.
ViewDidLoad:
/*Location Manager*/
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager setDistanceFilter:100.0];//Update location to network when player moves X meters
[locationManager setDesiredAccuracy:kCLLocationAccuracyKilometer];//Nearest 1000 meters (.33 miles)
[locationManager startUpdatingLocation];
/*Map View*/
mapLoaded = false;
currentFilter = 0;
[_mapView setDelegate:self];
[_mapView setShowsUserLocation:YES];
[_mapView setMapType:MKMapTypeSatellite];
Location Manager Delegate:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
//Wait until User Location is initialized (NOT 0,0)
NSLog(#"Latitude: %f, Longitude: %f",_mapView.userLocation.coordinate.latitude,_mapView.userLocation.coordinate.longitude);
if(_mapView.userLocation.location.coordinate.latitude!=0.00 && _mapView.userLocation.location.coordinate.longitude!=0.00){
//Update Player Object
[player setLatitude:_mapView.userLocation.location.coordinate.latitude];
[player setLongitude:_mapView.userLocation.location.coordinate.longitude];
[player updatePlayerLocation];//Update location to network
if(mapLoaded){//Map already loaded, call refresh
[self refreshMap];
}
else{//First load of map
[_mapView setCenterCoordinate:_mapView.userLocation.location.coordinate];
[self populateMap];
[self openVault];
mapLoaded = true;//Disable map first load
//timerMap = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:#selector(refreshMap) userInfo:nil repeats:YES];//Auto-Refresh of Map
}
}
}
You seem to be trying to get the location from the _mapView.userLocation CLLocation object.
You should rather use the last item in the locations array passed into your method.
see also documentation, guide with snippets

show Pin always in center on map view and calculate lat long,address in ios

In my ios application i want to place a pin on map that will always show callout by default.on that callut i am showing lat,long of pin.
What i want is pin always remain in center of map.and when user move map pin do not get moved but its lat long get changed after moving map.
i also want to show address from that lat,long.
Please guide what are the ways.
i have tried this code to
[mMapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
MyAnnotation* obj = [[MyAnnotation alloc] initWithLocation:mMapView.centerCoordinate withPinType:StartPoint];
[obj setTitle:[NSString stringWithFormat:#"%f, %f",mMapView.centerCoordinate.latitude,mMapView.centerCoordinate.longitude]];
[mMapView selectAnnotation:obj animated:YES];
[mMapView addAnnotation:obj];
zoom map at current location
add pin on map center
showing lat long
Problem - when i move map.pin also get moved and lat long did not get changed
In your -viewDidLoad method add following code,
[mMapView.userLocation addObserver:self
forKeyPath:#"location"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:NULL];
Now include the following method,
// Listen to change in the userLocation
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
[object setTitle:[NSString stringWithFormat:#"%f, %f",mMapView.centerCoordinate.latitude,mMapView.centerCoordinate.longitude]];
[mMapView selectAnnotation:object animated:YES];
}
Please make sure your annotation object is class object.
Hope this will help...

Resources