Can't add user location button on an iOS 6 map - iphone

I'm developing an application that uses an iOS 6 MKMap view and I would like to enable the "user location button" (the one that you see at the bottom-left of the screen when you are using the Maps application).
I didn't find anything that could help me so I've tried to make this button myself with this code:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D currentCoordinates;
currentCoordinates.latitude = newLocation.coordinate.latitude;
currentCoordinates.longitude = newLocation.coordinate.longitude;
MKCoordinateRegion viewRegion = MKCoordinateRegionMake(currentCoordinates, _mapView.region.span);
[_mapView setRegion:viewRegion animated:YES];
[locationManager stopUpdatingLocation];
}
- (IBAction)moveToCurrentLocation:(id)sender {
[locationManager startUpdatingLocation];
}
So when I press the button the locationManager updates user's current location and the map changes it's region with a new one centered on user's current location and with the same span.
Now I have another problem: when I press the button the maps moves to the right coordinates but it also zooms out (in other words the span increases) even if I crete a new region with the old span.
I can't understand this behavior, I would like to preserve the old span as the Map app does.

That button on maps is toggling the userTrackingMode property on the mapView, so set it to one of these:
MKUserTrackingModeNone //nothing, normal map view
MKUserTrackingModeFollow //user is highlighted and stays centered on map when you move
MKUserTrackingModeFollowWithHeading //you get the heading as well, so your direction is up on the map

If you want to use the official iOS button for that, this code will add it to your UIToolbar and connect it to your mapview
UIBarButtonItem *trackingButton = [[MKUserTrackingBarButtonItem alloc] initWithMapView:self.mapView];
NSMutableArray *items = [[NSMutableArray alloc] initWithArray:self.toolbar.items];
[items addObject:trackingButton];
[self.toolbar setItems:items];

Related

path tracing on map in ios

Some one help me out please I am stuck on it from last few days...
My task is here.
In my app i need to integrate the map, as it open it should shows the current user position, as i pressed start button while walking it starts tracing path from the position where i pressed start button till the position i pressed stop.the distance covered in this interval should be traced turn by turn navigation and also wann to collect start and stop position coordinates to calculate distance.
i have added map kit framework, core location frame work, also added map view,and also implemented method to show current user position . now
here is my code
-(void)startSignificantChangeUpdates
{
// Create the location manager if this object does not
// already have one.
if (nil == self.locatioManager)
{
self.locatioManager = [[CLLocationManager alloc] init];
self.locatioManager.delegate = self;
[self.locatioManager startMonitoringSignificantLocationChanges];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// If it's a relatively recent event, turn off updates to save power
CLLocation* location = [locations lastObject];
NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0) {
// If the event is recent, do something with it.
NSLog(#"latitude %+.6f, longitude %+.6f\n",location.coordinate.latitude,location.coordinate.longitude);
}
MKCoordinateRegion ref=MKCoordinateRegionMakeWithDistance([location coordinate], 250,250);
[self.myMapView setRegion:ref animated:YES];
}
Please guide me from here to trace path, and can collect coordinates also .

Center maps in iOS Programming

How do we follow the user in maps. I want to have the blue dot (user location) be in the center of the map, But I also what to allow the user to zoom in and zoom out and then after a couple seconds zoom in back in the user location.
My Educated Guess for the Solution: We detect if the user is zooming in or out, after three seconds of no zooming in or out detection, we starting follow the user :). Your HELP would be awesome :)
This code zoom in the user location but doesn't delay for zoom in and out:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
MKCoordinateRegion userLocation = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 1500.0, 1500.0); [mapView setRegion:userLocation animated:YES];
}
A quick look in the docs reveals the magic.
Set the userTrackingMode of your map to MKUserTrackingModeFollow.
See here.
Update:
Since you've updated your question, here's the new answer.
To recenter the map to the user location i would recommend to write a simple helper Method:
- (void)recenterUserLocation:(BOOL)animated{
MKCoordinateSpan zoomedSpan = MKCoordinateSpanMake(1000, 1000);
MKCoordinateRegion userRegion = MKCoordinateRegionMake(self.mapView.userLocation.coordinate, zoomedSpan);
[self.mapView setRegion:userRegion animated:animated];
}
And now you should call it after a short delay if user has stopped moving the map. You can do this in the regionDidChange delegate method of the mapView.
But you can get problems if you don't lock the reset-method if the user changes the region multiple times before it really resets the map. So it would be wise to make a flag if it is possible to recenter the map. Like a property BOOL canRecenter.
Init it with YES and update the recenterUserLocation method to:
- (void)recenterUserLocation:(BOOL)animated{
MKCoordinateSpan zoomedSpan = MKCoordinateSpanMake(1000, 1000);
MKCoordinateRegion userRegion = MKCoordinateRegionMake(self.mapView.userLocation.coordinate, zoomedSpan);
[self.mapView setRegion:userRegion animated:animated];
self.canRecenter = YES;
}
Now you can call it safely after the user has moved the map in any way with a small delay:
- (void)mapView:(MKMapView *)mMapView regionDidChangeAnimated:(BOOL)animated{
if (self.canRecenter){
self.canRecenter = NO;
[self performSelector:#selector(recenterUserLocation:) withObject:#(animated) afterDelay:3];
}
}
I had the same problem. I guessed:
If the user drag the map, he wants to stay on that position.
If the user do nothing or reset to show current location, I need to follow the user.
I added a reset button to show the current user location like this:
On the reset button clicked, changed the needToCenterMap to TRUE
Added a drag gesture recognizer on map
// Map drag handler
UIPanGestureRecognizer* panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(didDragMap:)];
- (void)didDragMap:(UIGestureRecognizer*)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateEnded){
NSLog(#"Map drag ended");
self.needToCenterMap = FALSE;
}
}
Followed the user on map depending on needToCenterMap flag
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
if (self.needToCenterMap == TRUE)
[mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}
I made a little example to show how you can delegate this job to the Map SDK.
Of course you could listen to the Location change but MKUserTrackingModeFollow automatically does this for you, so just a single line of code
#import <MapKit/MapKit.h>
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
MKMapView *mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
//Always center the dot and zoom in to an apropriate zoom level when position changes
[mapView setUserTrackingMode:MKUserTrackingModeFollow];
//don't let the user drag around the the map -> just zooming enabled
[mapView setScrollEnabled:NO];
[self.view addSubview:mapView];
}
Then the app looks like this:
For more information just read the Apple Documentation:
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html
This shell do the trick: mkMapview.showsUserLocation = YES;

iPhone - User location not showing when updated with CLLocation manager on iOS 3.x

I have a mapview which when pushed with its view controller onto the screen shows the location of a
user and some other custom annotations. when the view controller is pushed to screen it calls a function -(void)adduserLocation which shows the location of the user.
I also have a refresh button which also calls -(void)adduserLocation and refreshes all of the annotations and the user location but when the refresh button is pressed the users location does not appear on the map even though all of the same callbacks and updates are being registered (I can see that the user location is received and all the necessary callbacks are made)
I am using :
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil; //for some reason this is only being returned when the view is pushed and the get
//location method is called but not when the same location method is called
//while the view already exists.
}
and:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"User location: %f, %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
currentRegionLat = newLocation.coordinate.latitude;
currentRegionLng = newLocation.coordinate.longitude;
CLLocationCoordinate2D coord = {latitude: newLocation.coordinate.latitude, longitude: newLocation.coordinate.longitude};
MKCoordinateSpan span = {latitudeDelta: 0.006, longitudeDelta: 0.006};
MKCoordinateRegion region = {coord, span};
[mView setRegion:region];
[self getCardsInLocationLat:newLocation.coordinate.latitude andLng:newLocation.coordinate.longitude]; //this is a function which sets the annotations
}
I have no idea what I may be doing wrong. Please help. Thanks.
*UPDATE**
I have managed to find the source of the problem and work around it:
The problem was that I was removing all the annotations on the map before doing a location update
and for some reason the user location annotation was not being added.
So what I did is simply remove only all the non [MKUserLocation class] annotations and left
the user location annotation. This solved my problem but I still think that either there is some
kind of apple bug here or I am doing something wrong which I cannot yet see.
Hey, why don't you just set the MKMapView property, showsUserLocation, to YES?
mapView.showsUserLocation = YES;
This way you wouldn't really need to worry about refreshing the location.
If you don't want to use it for battery saving purposes or something, I think we would need to see more of your code. The code that you have doesn't seem to be where the problem lies. Do you get any errors in the console?

Current Location Problem using MKMapView in iPhone?

I am integrating map feature into my application. I have displayed the current location. In my problem is, i am developing two applications and displayed the current location. But both the applications displayed the current location in different location and different view in the map. See my screenshots
Both the screenshots are taken by simulator with two applications and it shows the different Map view frame. But i have used the same code for that.(This happens in device also, show the different place with the map frame). I donno why the map view frame is changed? I have created the map view frame in XIB. And i have included the required frameworks and switched on the location services. Why the Map frame view change? It's weird to me.
Here my sample code is,
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
[mapview setShowsUserLocation:YES];
[locationManager startUpdatingLocation];
}
- (void)locationManager: (CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
MKCoordinateRegion region1;
region1.center = newLocation.coordinate;
//Change the Zoom level of the current location
//region1.span.latitudeDelta = 0.1;//0.0001
//region1.span.longitudeDelta = 0.1; //0.0001
mapview.mapType = MKMapTypeStandard;
//[mapview setRegion:region1 animated:TRUE];
[locationManager stopUpdatingLocation];
}
I hope, the first screen shot map view frame is correct. Because i have passed the map view co-ordinates(North East, North West, South East and South West) to the server. If the frame size is wrong, i will get the wrong user details from the server.
Please help me out.
Thanks!
The lines in your locationManager:didUpdateToLocation:fromLocation: that are commented out are required for the map view to be updated. You need the call to [mapView setRegion:animated] in order to change the view region. Is your code definitely the same in both applications?
I assume that you know that in the simulator the current location is always the Apple headquarters in Cupertino, as shown in your first screenshot.

MKMapView annotation position update problem

I need to track user current location with realtime refreshrate
I have one function with two solutions for that.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
# ifdef Variant_1
if(m_currentLocation)
[m_Map removeAnnotation:m_currentLocation];
else
m_currentLocation = [MKPlacemark alloc];
[m_currentLocation initWithCoordinate:newLocation.coordinate addressDictionary:nil];
[m_Map addAnnotation:m_currentLocation];
[m_Map setCenterCoordinate:m_currentLocation.coordinate animated:YES];
# else //Variant_2
if(m_currentLocation == nil)
{
m_currentLocation = [MKPlacemark alloc];
[m_currentLocation initWithCoordinate:newLocation.coordinate addressDictionary:nil];
[m_Map addAnnotation:m_currentLocation];
}else
{
[m_currentLocation initWithCoordinate:newLocation.coordinate addressDictionary:nil];
//[m_currentLocation setCoordinate:newLocation.coordinate];
}
[m_Map setCenterCoordinate:m_currentLocation.coordinate animated:YES];
# endif
}
Variant_1 works good but when you move fast the location sing on the map blinks.
Variant_2 does not blink but does not move location sing however moves map.
Where is the problem?
In Variant_1, it probably blinks because you're doing a removeAnnotation and then an addAnnotation instead of just modifying the coordinates of the existing annotation.
In Variant_2, initWithCoordinate returns a new MKPlacemark object with those coordinates. It doesn't update the properties of the object you are calling the method on.
What happens if you run the setCoordinate line instead?
A separate question is why not use the MKMapView's built-in ability to show the current user location? Just do m_Map.showsUserLocation = YES; at the start. You don't need CLLocationManager to get the user's current location if you are using the MKMapView anyway.
I think you'll still need to center the map on the user's current location using one of the map view delegate methods:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
[mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}