I have a map view that does not always load locations (it seems like the more remote locations i.e. not main cities), only the grid and pin is shown but no map, and I see it is only when i am on the WIFI. The wifi appears to be solid, is this a known problem and is it resolvable? I've put my code in below although as i say it works for most locations, 100% on 3g less so on WIFI. The mapView is inside a webView
self.mapView.scrollEnabled = true;
self.mapView.zoomEnabled = true;
MKCoordinateSpan span = MKCoordinateSpanMake(0.003, 0.003);
MKCoordinateRegion region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(-26.204029, 28.039171), span);
[_mapView setRegion: region];
MapAnnotation *annotation = [[[MapAnnotation alloc] initWithCoordinates: region.center
title: #""
subTitle: #""] autorelease];
[self.mapView addAnnotation: annotation];
Related
I have a map region with about ten annotated MapPin objects (coordinates retrieved from a plist). In the code below 'locations' is a NSMutable array object containing the pin annotation latitude and longitude.
for (int i = 0; i<[locations count]; i++) {
MKCoordinateSpan span = MKCoordinateSpanMake(0, 0);
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(0, 0);
pinRegion = MKCoordinateRegionMake(center, span);
MapPin *pin = [[MapPin alloc] init];
pinRegion.center.longitude = [locations[i][0] doubleValue];
pinRegion.center.latitude = [locations[i][1] doubleValue];
pin.title = names[i];
pin.coordinate = pinRegion.center;
[self.mapView addAnnotation:pin];
}
By selecting any pin I want to return its coordinate. I can inspect any pin object address like this:
NSLog(#"%#", self.mapView.selectedAnnotations);
... shows a unique address for a selected pin such as "<MapPin: 0x16d2f610>"
But I don't know how to access the objects coordinate properties such as longitude and latitude.
Please can you help?
Thank you!
Make sure your map view has its delegate assigned (in this example we will use your view controller)
mapView.delegate = self
Next handle the callback delegate for annotation taps like this:
Swift
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView)
{
if let annotationCoordinate = view.annotation?.coordinate
{
print("User tapped on annotation with title: \(annotationCoordinate")
}
}
Objective - C
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
NSLog(view.annotation.coordinate);
}
Let me know if you have any questions
When I create the story board below the map over takes the entire screen. This is understandble with the code that I have below it uses the entire bounds of the view. However, if I do a normal "init", I lose functionality of the map! The map usually zooms into my location, and a few other things. When I use init instead of initWithFrame the map doesn't go to my location.
self.myMapView =[[MKMapView alloc]initWithFrame:self.view.bounds];
self.myMapView.delegate=self;
How do I initialize the map without having it take over the entire screen like shown in my story board. New to iOS, thanks for your help!
//Setting up the location manger for finding the User's location
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;
//Check to see if they have Authorization to use to use location servieces
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)])
{
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
//Initialize the map and specifiy bounds
self.myMapView =[[MKMapView alloc]initWithFrame:self.view.bounds];
//Set the delegate to itself
self.myMapView.delegate=self;
//Set a standard mapview, Enable scrolling and zooming
self.myMapView.mapType = MKMapTypeStandard;
self.myMapView.scrollEnabled = YES;
self.myMapView.zoomEnabled = YES;
//specifcy resizing
self.myMapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
//show the User's location and set tracking mode
self.myMapView.showsUserLocation = YES;
self.myMapView.userTrackingMode = MKUserTrackingModeFollow;
//add the VIEW!!
[self.view addSubview:self.myMapView];
//Set up the UISearch Bar
self.mySearch = [[UISearchBar alloc]init];
self.mySearch.delegate = self;
//Set the initial Text
self.mySearch.prompt = #"Enter Address or Use Current Location";
There's two approaches to create your map view.
1.Create in code. As shown in your example. You need to set the map view frame. If you need firstly to create UISearchBar, you should set map view frame according to search bar position. It might look like this.
self.mySearch = [[UISearchBar alloc] init];
self.mySearch.frame = CGRectMake(0, 0, self.view.frame.size.width, 40);
//...
self.myMapView = [[MKMapView alloc] init];
self.myMapView.frame = CGRectMake(0, self.mySearch.frame.size.height, self.view.frame.size.width, self.view.frame.size.height - self.mySearch.frame.size.height);
//...
2.Much more simpler way - create in storyboard. Firstly, there no need to create your outlets (such as search bar and map view) in code. You simple drag'n'drop all the controls to view. Open your storyboard, set the view controller class from UIViewController to your class name.
Note that the properties must be IBOutlets
#property (nonatomic,weak) IBOutlet MKMapView *myMapView;
#property (nonatomic,weak) IBOutlet UISearchBar *mySearchBar;
After dropping your controls to view, you must connect visual controls to your class outlets. Take a look at this tutorial where connections are explained.
I am just looking at mapKit and decided to make a quick button to display my current location, however when I press the button my latitude/longitude always display as [0.000000] [0.000000].
The mapView is loaded as I can see the map on the simulator before I press the button. Previously I have done this by using coreLocation.framework and using CLLocationManager and asking for the device location that way. I am just curious why this way is not working correctly, would I be better doing this via CLLocationManager?
-(IBAction)findMePressed {
MKUserLocation *myLocation = [myMapView userLocation];
CLLocationCoordinate2D coord = [[myLocation location] coordinate];
[myMapView setCenterCoordinate:coord animated:YES];
NSLog(#"findMePressed ...[%f][%f]", coord.latitude, coord.longitude);
}
EDIT: Added ...
-(IBAction)findMePressed {
MKUserLocation *myLocation = [myMapView userLocation];
CLLocationCoordinate2D coord = [[myLocation location] coordinate];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 350, 350);
[myMapView setRegion:region animated:YES];
}
-(void)viewDidLoad {
[super viewDidLoad];
[myMapView setShowsUserLocation:YES];
}
Gary.
Either the userLocation is not visible on the map (see the userLocationVisible property) or there is some problem setting up the myMapView property and it's nil (i.e. not connected in interface builder)
[...] as I can see the map on the simulator [...]
Test it on the device. By default, on the simulator, the coordinates you get back are Apple's headquarters. Cf. doc.
See this other SO question for workarounds and useful utilities : Testing CoreLocation on iPhone Simulator
I need to draw a circle to display the distance around a point that I have plotted.
Where should I implement these two lines of code to make it work? I tried putting it in viewWillAppear: but the circle does not appear.
[self addCircle:_coordinate];
[self addCircleWithRadius:5.5 addCircleWithCoordinate:_coordinate];
- (void)addCircle: (CLLocationCoordinate2D)coordinate
{
// draw the radius circle for the marker
double radius = 2000.0;
MKCircle *circle = [MKCircle circleWithCenterCoordinate:coordinate radius:radius];
[circle setTitle:#"background"];
[_mapView addOverlay:circle];
MKCircle *circleLine = [MKCircle circleWithCenterCoordinate:coordinate radius:radius];
[circleLine setTitle:#"line"];
[_mapView addOverlay:circleLine];
}
- (void)addCircleWithRadius:(double)radius addCircleWithCoordinate: (CLLocationCoordinate2D) coordinate
{
MKCircle *circle = [MKCircle circleWithCenterCoordinate:coordinate radius:radius];
[circle setTitle:#"background"];
[_mapView addOverlay:circle];
MKCircle *circleLine = [MKCircle circleWithCenterCoordinate:coordinate radius:radius];
[circleLine setTitle:#"line"];
[_mapView addOverlay:circleLine];
}
- (void)sliderChanged:(UISlider*)sender
{
[_mapView removeOverlays:[_mapView overlays]];
double radius = (sender.value * 100);
CLLocationCoordinate2D coordinate = self.coordinate;
[self addCircleWithRadius:radius addCircleWithCoordinate:coordinate];
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay{
MKCircle *circle = overlay;
MKCircleView *circleView = [[[MKCircleView alloc] initWithCircle:overlay] autorelease];
if ([circle.title isEqualToString:#"background"])
{
//circleView.fillColor = UIColorFromRGB(0x598DD3);
circleView.alpha = 0.25;
}
else
{
//circleView.strokeColor = UIColorFromRGB(0x5C8AC7);
circleView.lineWidth = 2.0;
}
return circleView;
}
While you could try viewDidAppear instead of viewWillAppear, I think it should already work in that regard. I think that you have something else wrong, and you should step through with a debugger to find it. Check the usual suspects:
Set the fill color. Make it opaque and obvious.
_mapView might be nil or zombied during runtime. (or not mapped in your xib)
The coordinates or radius may be different than you expect. Check the actual coordinate values in your debugger.
Everything may be correct except that the coordinates are not located in your map's zoomed area.
My problem occurs only on iPad. There is always unrendered portion of MKMapView(right side on the picture below). As soon as I touch this window the mapview repaints itself just fine. But it never renders correctly right away. This problem occures in iOS 4.2 as well as in iOS 3.2 in Simulator and the Device. The code that constructs MKMapView is right below:
- (void)viewDidLoad {
[super viewDidLoad];
mapview = [[[MKMapView alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width,230)] autorelease]; // because of apples bug
mapview.autoresizingMask = UIViewAutoresizingFlexibleWidth;
MKCoordinateSpan globe = MKCoordinateSpanMake(100, 100);
CLLocationCoordinate2D worldCenter; worldCenter.latitude = 42.032974; worldCenter.longitude =21.359375;
MKCoordinateRegion worldmap = MKCoordinateRegionMake(worldCenter, globe);
mapview.region = worldmap;
mapview.zoomEnabled = NO;
mapview.showsUserLocation = YES;
mapview.delegate = self;
NSRange theRange;
theRange.location = 1;
theRange.length = [annotations count]-1;
[mapview addAnnotations:[annotations subarrayWithRange:theRange]];
[self.view addSubview:mapview];
}
The problem manifests itself only in Landscape orientation.
UPDATE
This is how it spans after I touched the view.
Nonetheless it's Apple's bug. In iPad-landscape mode your longtitude span may not be enough to cover 360degree of the globe. it should autoscale with zoom, but it doesn't. it autozooms properly only if your centerMap is exactly at 0 degree longitude. Weird.
Workaround:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
CLLocationCoordinate2D worldCenter; worldCenter.latitude = 42.032974;
worldCenter.longitude = UIDeviceOrientationIsLandscape(toInterfaceOrientation)? 0.0 : 21.359375;
mapview.centerCoordinate = worldCenter;
}
I did a quick test with your code and get the same result (which I expected). I still think it is not an issue with the map itself but with the way you are setting your center coordinates plus map span. You're trying to center the map too far to the left with max span and the only way for the map to fill the entire screen and maintain the center point would be for it to stretch itself, which is not desirable. If you set lat and long to 0 you get the same view without the missing part.