MKMapView won't respond to touching or pinching - ios

So I have a MKMapVie object and it is set up as follows:
self.mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0,
[Screen width],
[Screen height])];
self.mapView.mapType = MKMapTypeSatellite;
self.mapView.userInteractionEnabled = YES;
self.mapView.scrollEnabled = YES;
self.mapView.showsUserLocation = YES;
[self addSubview:mapView];
And I set its location to be the current user location with the following method.
- (void) locateUser {
float z2 = 0.003 * 4.0;
MKCoordinateSpan span = MKCoordinateSpanMake(z2, z2);
[self.mapView setRegion: MKCoordinateRegionMake(currentLocation, span) animated:YES];
}
However once the map zooms to the users location it will not allow me to move the map around or pinch or zoom. Is there something i'm missing?
Thanks.

Related

Why doesn't this zoom functionality work in Google Maps iOS app?

I am trying to set up a way for the user to change the zoom of the map. Here's the code I have. What's the problem? Is there no implementation for invoking the zoom functionality? or is it that I set self.mapView.camera twice, in two different functions (viewDidLoad and ZoominOutMap)?
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//Controls whether the My Location dot and accuracy circle is enabled.
CGFloat currentZoom = 14.0f;
self.mapView.myLocationEnabled = YES;
//adds type of map: kGMSTypeSatellite, kGMSTypeTerrain, kGMSTypeHybrid, kGMSTypeNormal
self.mapView.mapType = kGMSTypeHybrid;
//Shows the compass button on the map
self.mapView.settings.compassButton = YES;
//Shows the my location button on the map
self.mapView.settings.myLocationButton = YES;
//Sets the view controller to be the GMSMapView delegate
self.mapView.delegate = self;
GMSCameraPosition *manhattan = [GMSCameraPosition cameraWithLatitude:40.790278
longitude:-73.959722
zoom:14];
self.mapView.camera = manhattan;
}
//setting up zoom
-(void)ZoominOutMap:(CGFloat)level
{
self.mapView.delegate = self;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:40.790218 longitude:-73.959722
zoom:level];
self.mapView.camera = camera;
}
-(void)zoomInMapView:(id)sender
{
CGFloat currentZoom;
currentZoom = currentZoom + 1;
[self ZoominOutMap:currentZoom];
}
-(void) zoomOutMapView:(id)sender
{
CGFloat currentZoom;
currentZoom = currentZoom - 1;
[self ZoominOutMap:currentZoom];
}
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate
{
NSLog(#"You tapped at %f,%f", coordinate.latitude, coordinate.longitude);
GMSMarker *marker = [[GMSMarker alloc] init];
//adds animation for adding marker
marker.appearAnimation = kGMSMarkerAnimationPop;
//draw marker on tapped position
marker.position = CLLocationCoordinate2DMake(coordinate.latitude,coordinate.longitude);
marker.map = _mapView;
//set color of marker and make them draggable
marker.icon = [GMSMarker markerImageWithColor:[UIColor blueColor]];
[marker setDraggable: YES];
// Create a rectangular path
GMSMutablePath *rect = [GMSMutablePath path];
[rect addCoordinate:CLLocationCoordinate2DMake(coordinate.latitude,coordinate.longitude)];
// Create the polygon, and assign it to the map.
GMSPolygon *polygon = [GMSPolygon polygonWithPath:rect];
polygon.fillColor = [UIColor colorWithRed:0.25 green:0 blue:0 alpha:0.05];
polygon.strokeColor = [UIColor blackColor];
polygon.strokeWidth = 2;
polygon.map = _mapView;
}
You forget to add action to the buttons:
If buttons are added programatically :
[zoomOut addTarget:self
action:#selector(zoomOutMapView:)
forControlEvents:UIControlEventTouchUpInside];
[zoomOut addTarget:self
action:#selector(zoomInMapView:)
forControlEvents:UIControlEventTouchUpInside];
For Storyboard :
//zoom controls 
- (IBAction)zoomOut:(id)sender { 
currentZoom = currentZoom - 1; 
[self zoomHandler:currentZoom]; 
} 
- (IBAction)zoomIn:(id)sender { 
currentZoom = currentZoom + 1; 
[self zoomHandler:currentZoom]; 
} 
- (void)zoomHandler:(CGFloat)level 
{ 
self.mapView.delegate = self; 
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:40.790218 longitude:-73.959722 zoom:level]; 
self.mapView.camera = camera; 
}

MkmapView: How to keep the map centered while the user zoom

I'm trying to implement the same map behaviour has Uber.
I would like to keep the map centered while the user zoom the map with a pinch or a double tap.
I tried implementing my own gesture recognizer but the result isn't great...
Does anyone got an idea of how to do it ?
Thanks !
For those interested in the solution i managed to do it.
First you need to add your gesture recognizer in the viewDidload
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(pinchOnMap:)];
[pinch setDelegate:self];
[pinch setDelaysTouchesBegan:YES];
[self.mapGestureContainer addGestureRecognizer:pinch];
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(zoomInGesture:)];
gestureRecognizer.delegate = self;
[gestureRecognizer setDelaysTouchesBegan:YES];
gestureRecognizer.numberOfTapsRequired = 2;
[self.mapGestureContainer addGestureRecognizer:gestureRecognizer];
Then implement the gesture function, it will handle the zoom based on the pinch scale. I added a small delay to avoid too much processing.
-(void) zoomInGesture:(UITapGestureRecognizer *) recognizer {
currentRegion = self.mapView.region;
currentSpan = self.mapView.region.span;
isZoomingWithDoubleTap = YES;
MKCoordinateRegion region = currentRegion;
MKCoordinateSpan span = currentSpan;
span.latitudeDelta = currentSpan.latitudeDelta / 2.3;
span.longitudeDelta = currentSpan.longitudeDelta / 2.3;
region.span = span;
[self.mapView setRegion:region animated:YES];
}
//Gesture used when the user pinch the area of the map
- (void) pinchOnMap:(UIPinchGestureRecognizer *) recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
isPinching = YES;
self.mapView.scrollEnabled = NO;
self.mapView.userInteractionEnabled = NO;
currentRegion = self.mapView.region;
currentSpan = self.mapView.region.span;
lastZoomTime = [[NSDate date] timeIntervalSince1970];
}
if (recognizer.state == UIGestureRecognizerStateEnded) {
isPinching = NO;
self.mapView.scrollEnabled = YES;
self.mapView.userInteractionEnabled = YES;
}
if (recognizer.state == UIGestureRecognizerStateChanged) {
if (([[NSDate date] timeIntervalSince1970] * 1000) - lastZoomTime >= 20) {
lastZoomTime = [[NSDate date] timeIntervalSince1970] * 1000;
MKCoordinateRegion region = currentRegion;
MKCoordinateSpan span = currentSpan;
span.latitudeDelta = currentSpan.latitudeDelta / recognizer.scale;
span.longitudeDelta = currentSpan.longitudeDelta / recognizer.scale;
region.span = span;
[self.mapView setRegion:region animated:NO];
}
}
}
In your map view delegate, do this
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
[mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}

How to Set a Region for a MKMapView?

I am new in iOS apps development and I want to put a Map in My application with a pushpin on an exact location using its latitude and longitude. I add the Map but the problem is it always appear with its initial position an the push pin doesn't appear (It is on the map but you need to change the position to see it ) . Like this figures shows :
Initial Position
2.- After I moved the map's position
What I want is to show the position of the pushpin as a default location and with a zoom .
This is a sample of My Code :
- (void)viewDidLoad
{
[super viewDidLoad];
CLLocationCoordinate2D myCoordinate = {20.5, -7.06}; //AS an Example
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = myCoordinate;
//Drop pin on map
[self.mapView addAnnotation:point];
//Region with Zoom
-(void)viewWillAppear:(BOOL)animated {
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = 20.5;
zoomLocation.longitude= -7.6;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
[self.mapView setRegion:viewRegion animated:YES];
}
I used this code but still the same thing it always display the initial position (Figure 1)
Thank You .
(void)viewDidLoad
{
[super viewDidLoad];
MapAnnotation *ann = [[MapAnnotation alloc] init];
MKCoordinateRegion region;
region.center.latitude = 31.504679;
region.center.longitude = 74.247429;
region.span.latitudeDelta = 0.01;
region.span.longitudeDelta = 0.01;
[mapView setRegion:region animated:YES];
ann.title = #"Digital Net";
ann.subtitle = #"Office";
ann.coordinate = region.center;
[mapView addAnnotation:ann];
}
(MKAnnotationView *) mapView:(MKMapView *)mpView viewForAnnotation:(id)annotation {
MKPinAnnotationView *pinView = nil;
if(annotation != mapView.userLocation) {
static NSString *defaultID = #"myLocation";
pinView = (MKPinAnnotationView *)[mpView dequeueReusableAnnotationViewWithIdentifier:defaultID];
if(pinView == nil) {
pinView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:defaultID];
pinView.pinColor = MKPinAnnotationColorGreen;
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
}
}
return pinView;
}
I have done something like that and it was working fine

Incorrect user location shown on MKMapView after scaling the map programmatically

I have MKMapView which have UserTrackingMode = MKUserTrackingModeFollow,
and I have adding a circle overlay to show a region of the certain diameter at user location.
Also user can change the diameter of the region so I want to scale the map to insure whole region/circle is shown on that portion of the map.
The problem I have now is that scaling the map number of times by setting region results in incorrect user location annotation - it is moved from the correct location.
I cannot understand why is that happens, I see in the debugger that the mapView.userLocation property have correct coordinates.
But once new update is happens or I move the map manually - the annotation jumps to the correct place.
This is the code:
- (void)addCircleWithRadius:(double)radius andCoordinate:(CLLocationCoordinate2D)coordinate
{
_regionCircle = [MKCircle circleWithCenterCoordinate:coordinate radius:radius];
[_regionCircle setTitle:#"Region"];
MKCoordinateRegion region;
region.center.latitude = coordinate.latitude;
region.center.longitude = coordinate.longitude;
region.span.latitudeDelta = 0.00002 * _regionCircle.radius;
region.span.longitudeDelta = 0.00002 * _regionCircle.radius;
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits: region];
[self.mapView setRegion:adjustedRegion animated:TRUE];
_circleView = nil;
[self.mapView addOverlay:_regionCircle];
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
if(!_circleView)
{
_circleView = [[MKCircleView alloc] initWithCircle:overlay];
_circleView.strokeColor = [UIColor blueColor];;
_circleView.fillColor = [UIColor blueColor];
_circleView.alpha = 0.25;
_circleView.lineWidth = 2.0;
}
return _circleView;
}
- (IBAction)regionSliderValueChanged:(id)sender
{
[self updateRadiusCircle];
}
- (void) updateRadiusCircle
{
[self.mapView removeOverlays:self.mapView.overlays];
CLLocationCoordinate2D myCoordinate = {_currentLocation.coordinate.latitude, _currentLocation.coordinate.longitude};
[self addCircleWithRadius:self.radiusSlider.value andCoordinate:myCoordinate];
}
I have published the video on YouTube to better understand the issue.
https://www.youtube.com/watch?v=474gdjkGwJA

MKCircle is not updating radius but it's translating

I've to draw an MKCicle into an MKMapView. Then I've to re-draw it when user, through a slider, change the radius. I remove it and I re-create it, re-adding it to the map.
But instead of do what I'm expecting, I see the MKCircle translating over the map, maintaining the same size.
Here's my code:
- (MKOverlayView *)mapView:(MKMapView *)map viewForOverlay:(id)overlay
{
MKOverlayView* overlayView = nil;
if(overlay == self.circle)
{
//if we have not yet created an overlay view for this overlay, create it now.
if(nil == self.circleView)
{
self.circleView = [[[MKCircleView alloc] initWithCircle:self.circle] autorelease];
self.circleView.fillColor = [UIColor blueColor];
self.circleView.strokeColor = [UIColor blueColor];
self.circleView.alpha = 50;
self.circleView.lineWidth = 2;
}
overlayView = self.circleView;
}
return overlayView;
}
-(void)drawPolygonWithLocation
{
[self.mapView removeOverlay: self.circle];
MKCoordinateRegion region;
region.center.latitude = self.geofenceLocation.latitude;
region.center.longitude = self.geofenceLocation.longitude;
region.span.latitudeDelta = 0.005;
region.span.longitudeDelta = 0.005;
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits: region];
[self.mapView setRegion:adjustedRegion animated:TRUE];
self.radius = (double)(slRadius.value);
NSLog(#"Raggio: %f", self.radius);
NSLog(#"Lat: %f, Lon: %f", region.center.latitude, region.center.longitude);
self.circle = [MKCircle circleWithCenterCoordinate:self.geofenceLocation.coordinate radius: self.radius];
NSLog(#"CIRCLE: radius %f Lat: %f, Lon: %f", self.circle.radius, self.circle.coordinate.latitude, self.circle.coordinate.longitude);
[self.mapView addOverlay:self.circle];
}
-(IBAction)updateRadius:(id)sender
{
[self drawPolygonWithLocation];
}
The NSLog is writing into the console right values, the center doesn't change and the radius changes according to the user input.
But, again, the MKCircle translates going on the north-west.
Thanks in advance,
Samuel Rabini
Fixed.
I just add
self.circleView = nil;
before the
[self.mapView addOverlay:self.circle];
in this way it works fine.
Samuel

Resources