I'm trying to set a custom starting region in an iOS app using MKMapView's setRegion. The app runs fine, and a map appears, but no matter what I try I can't get the region to change. I've tried many tutorials and solutions, but none are working. Here's my code:
-(void)viewDidAppear:(BOOL)animated{
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.001;
span.longitudeDelta = 0.001;
region.span = span;
region.center.latitude = 100;
region.center.longitude = 100;
[mapView setRegion:(region) animated:(TRUE)];
}
I have the MKMapView and Core Location frameworks added to the projects properly, I import MapKit.h, and I declare mapView, so I don't know why it's not working.
Thank you,
Jacob
It sounds like the map view's IBOutlet is not connected to the map view control in the xib/storyboard.
If it's not connected, the mapView variable will be nil and calling methods on it will do nothing.
In the xib/storyboard, right-click on View Controller and connect the mapView outlet to the map view control.
Additionally, although not necessary for just setting the region, also connect the map view's delegate outlet to the View Controller. This will be required if you later implement any map view delegate methods. If this is not done, the delegate methods won't get called.
Another separate point:
In your first code example, you are setting the region's center to 100, 100. Please note that this is an invalid coordinate. If the map view was actually connected, setting the center to this would have caused a crash with "Invalid Region". Latitude must be from -90 to +90 (longitude must be from -180 to +180).
By the way, the new coordinate you're trying in the code posted in the comment (26, 80) is in India. Since you're setting the span to a relatively small value, you'll need to zoom out a lot to see this.
However it was set as answered, I will let here an example of what worked for me, when I had no clue why setRegion was not working at all. In my case the problem was the I've initiated the MKMapView without a frame, e.g.:
override func viewDidLoad() {
...
self.mapView = MKMapView() // Wrong!
...
self.mapView.setRegion(...) // Does not work!
}
It looks like that the whole region thing is calculated with regards the the initial (CGRect). It worked for me by doing:
override func viewDidLoad() {
...
self.mapView = MKMapView(frame: CGRect(0, 108, self.mapView.bounds.width, self.mapView.bounds.height))
self.mapView.setRegion(...) // Oh, it works!
}
This problem was described here too.
Related
I need to create ViewController with MKMapView. When it opens, there are should appear current location and slowly zooming out for 10 seconds (or less, it doesn't matter actually). And when animation completed application should perform segue to the next ViewController. Any ideas?
There is no "direct" method for setting a zoom level. You can, however, simulate this by setting the distance, which causes the image to resize.
CLLocationCoordinate2D noLocation;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 500, 500);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
[self.mapView setRegion:adjustedRegion animated:YES];
self.mapView.showsUserLocation = YES;
You can either loop this, or simply set it twice, first to a BIG area and then the zoomed in area, and let the MapView's default animation do its thing.
I'm a beginner and have created a small project just to learn about mapview in which I set four button up down right left and set a airplane image at center like this
when we click on the up button the lattitude increases by 10 coordinates like 47->57->67 till 77 in in down like->-43->-53->-63 till -73 and same for left and right I only want to know that why it is changing the region and zoom out when I go up (when increase the lattitude) and zoom in (when decrease the lattitude) and how to fix it except that everything is working fine.
I'll put code for one button lets say UP for your better understanding:-
1.in viewDidLoad
lattitude=27;
2.in my viewController.m
- (IBAction)up:(id)sender {
if (lattitude<=70) {
_targetOutlet.image=[UIImage imageNamed:#"up"];
[UIView animateWithDuration:5 animations:^{
lattitude=lattitude+10;
centre=CLLocationCoordinate2DMake(lattitude, longitude);
map.userLocation.coordinate=centre;
region=[map regionThatFits:MKCoordinateRegionMakeWithDistance(centre, zoomScale ,zoomScale)];
[map setRegion:[map regionThatFits:region] animated:YES];
}];
}
NSLog(#"UP = Lattitude = %f longitude= %f",lattitude,longitude);
}
Note: The region is fixed in the entire project.
probably the problem is in you MKCoordinateRegionMakeWithDistance method where every time you are setting the latitudinalMeters longitudinalMeters parameters of this method.
MKCoordinateRegion MKCoordinateRegionMakeWithDistance ( CLLocationCoordinate2D centerCoordinate, CLLocationDistance latitudinalMeters, CLLocationDistance longitudinalMeters );
You can try this one:
region=[map regionThatFits:MKCoordinateRegionMakeWithDistance(centre, 200 ,200)];
or see apple doc for more info :)
I have a mapview in xcode, which is all working well.
What my page does just now is like this:
downloads a bunch of data and locations from a backend database
populates a mapview with locations and drops pins
populates a table underneath the mapview
That all works great, and I end up with a mapview with a load of pins, and a tableview that has the details of those pins.
What I want to do now, is allow the user to tap on a row from the tableview, and have the map zoom and centre to the corresponding map pin, and then automatically activate the annotation pin callout.
In my 'didselectrow' method, I have the following:
MKCoordinateSpan span = MKCoordinateSpanMake(0.1f, 0.1f);
CLLocationCoordinate2D coordinate = { [item.latitude floatValue], [item.longitude floatValue] };
MKCoordinateRegion region = { coordinate, span };
[self.mapView setRegion:region animated:YES];
This works great too. Tapping on the table row will zoom to and centre the map pin at this location.
I just can't get the last step of firing the annotation pin callout to work.
I have tried:
[mapview annotationsInMapRect:mapview.visibleMapRect];
But this isn't working, and it is possible that there still might be 2 or 3 map pins in the visible area.
What I need to do is to get the pin nearest to the centred location (see above - item.latitude / item.longitude) to automatically open it's callout.
Everything in the code is set up and working, and the map pins have callouts that fire when tapped on, I just need this last stage of having the pin nearest the centre location to open automatically.
Can anyone help with this?
I have tried various other suggestions on SO, but none seem to fit this requirement.
I think I have got solution for your problem you need to use this [_mapView setSelectedAnnotations:#[[[self.mapView annotations] lastObject]]];
For testing I have created an small project that have these 2 methods.
- (IBAction)buttonTouched:(id)sender {
[_mapView showAnnotations:[self.mapView annotations] animated:YES];
[self performSelector:#selector(showAnnotationCallOut) withObject:nil afterDelay:1.0f];
}
- (void) showAnnotationCallOut {
[_mapView setSelectedAnnotations:#[[[self.mapView annotations] lastObject]]];
}
Note: I have called just one annotation for test that why I am calling last object. You'll need to call it for specific annotation of your annotation array.
Edit: According to Richerd's comment here is solution for problem of finding the annotion and showing the callout fro that.
for (MapViewAnnotation *annotion in [self.mapView annotion]) {
if ([annotion.identifire isEqualToString:annotationToCallCallOutIdentifier]) {
//[_mapView setSelectedAnnotations:#[annotation]];
[_mapView selectAnnotation:annotation animated:YES];
break;//don't break if there are can be more than one callouts
}
}
In iOS 5 this worked fine, and I was under the impression that everything from MKMapKit would continue working in much the same way. However, instead of zooming to my location and adding annotations that I have set up, it just shows North America. I am leaving the annotations out of the code snippet I have, and just putting in the initial code setup.
[mapView setMapType:MKMapTypeSatellite];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
mapView.delegate = self;
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = 32.385325 ;
region.center.longitude = -86.217442;
region.span.longitudeDelta = 0.005f;
region.span.latitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
Any thoughts on why it is not zooming to where I have it set?
I personally don't suspect an iOS 6 v iOS 5 issue. This code works fine for me in iOS 6. So the problem rests elsewhere.
In short, a problem with the mapView variable seems far more likely. Have you checked to see that mapView is not nil? There are all sorts of simple candidate issues:
Perhaps you manually declared class instance variable for a property (which you should not do ... simply define your property and let the compiler synthesize your instance variable for you, precisely to avoid this sort of possible confusion); or
Perhaps there was a failure to link up the IBOutlet, etc.
I am trying to Geo-fence using Google Map for iPhone app.
A lot of tutorials can be found for MKMapView. But can't find for the GMSMapView.
The basic thing is how to convert the screen coordinate (x,y) to the MapCoordinate lat/lng.
Is there any API available for Google Map in iOS for that conversion?
Thanks
You can use something like this:
GMSMapView* mapView = ...;
CGPoint point = ...;
...
CLLocationCoordinate2D coordinate =
[mapView.projection coordinateForPoint: point];
UPDATE:
The comments on the projection property in GMSMapView.h are:
/**
* The GMSProjection currently used by this GMSMapView. This is a snapshot of
* the current projection, and will not automatically update when the camera
* moves. The projection may be nil while the render is not running (if the map
* is not yet part of your UI, or is part of a hidden UIViewController, or you
* have called stopRendering).
*/
#property (nonatomic, readonly) GMSProjection *projection;
Therefore you can only access the .projection property after the map has rendered. It will be nil if you try to access it during loadView or viewDidLoad.
I don't know if there is a better way to tell if the map has been rendered, but I noticed that the mapView:didChangeCameraPosition: method is called once after the map view is first displayed, and that the map's projection property is valid there.
So, in your view controller's header, add GMSMapViewDelegate:
#interface ViewController : UIViewController <GMSMapViewDelegate>
When you allocate the map view, assign the delegate:
_map = [GMSMapView mapWithFrame: CGRectMake(0, 0, width, height) camera: camera];
_map.delegate = self;
[self.view addSubview: _map];
Then add the delegate method:
- (void)mapView: (GMSMapView*)mapView
didChangeCameraPosition: (GMSCameraPosition*)position
{
CGPoint point = CGPointMake(x, y);
CLLocationCoordinate2D coordinate =
[_map.projection coordinateForPoint: point];
}
Note that mapView:didChangeCameraPosition: is called every time the user changes the camera, so you'd probably need to use a flag, so that you only do your calculations the first time mapView:didChangeCameraPosition: is called.
No need to convert x,y to lat,long.
GMSCircle *fence = [GMSCircle circleWithPosition:locationCord radius:fenceRadius];
[fence setFillColor:[UIColor colorWithRed:102.0/255 green:178.0/255 blue:255.0/255 alpha:0.3]];
[fence setZIndex:100];
[fence setMap: _map];
Add this code when you are making GMSMapView and geo fence will be shown with your location marker.