I am implementing SKMapView in my project. There I am showing user few annotations. On clicking I am displaying a UIView with some relevant information about those coordinates. Now if user clicks anywhere else in the map area. I want to hide this marker info view. I am capturing map click using below method
-(void)mapView:(SKMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate.
This is how I am showing annotation in my view
//create the SKAnnotationView
SKAnnotationView *view = [[SKAnnotationView alloc] initWithView:pinView reuseIdentifier:#"viewID"];
//create the annotation
SKAnnotation *viewAnnotation = [SKAnnotation annotation];
//set the custom view
viewAnnotation.annotationType = SKAnnotationTypePurple;
viewAnnotation.annotationView = view;
viewAnnotation.identifier = index;
viewAnnotation.location = coordinates;
SKAnimationSettings *animationSettings = [SKAnimationSettings animationSettings];
[self.skMapView addAnnotation:viewAnnotation withAnimationSettings:animationSettings];
Please help and tell how can i hide this info marker view. Thanks in advance.
Following method call will catch all click events on map.
-(void)mapView:(SKMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate
Here I am hiding the info view.
Related
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
}
}
I need to create a map view interface, which is something similar to the OLA Cabs Application in iOS. What I exactly wanna do is to fix an overlay on mapView and allow the user to scroll the map view across it. So that the overlay can be fixed at any location the User wants it to, I searched a lot about overlays, in iOS and MapKit, but couldn't make it possible. If some one can give me tips for achieving this I would be really grateful. Here is a snapshot of the screen
Here the annotation remains fixed and you can move the map view across it, So that when you stop the mapview, the overlay will be pointing to the new location, where you stopped
Click here to download demo...
Create a fix MKAnnotation and image view object to animating the location change effect in Map view.
#property (nonatomic, strong) CustomAnnotation *fixAnnotation;
#property (nonatomic, strong) UIImageView *annotationImage;
Add this code in viewDidLoad() method:
// Fix annotation
_fixAnnotation = [[CustomAnnotation alloc] initWithTitle:#"Fix annotation" subTitle:#"Location" detailURL:nil location:self.mapView.userLocation.coordinate];
[self.mapView addAnnotation:self.fixAnnotation];
// Annotation image.
CGFloat width = 64;
CGFloat height = 64;
CGFloat margiX = self.mapView.center.x - (width / 2);
CGFloat margiY = self.mapView.center.y - (height / 2) - 32;
// 32 is half size for navigationbar and status bar height to set exact location for image.
_annotationImage = [[UIImageView alloc] initWithFrame:CGRectMake(margiX, margiY, width, height)];
[self.annotationImage setImage:[UIImage imageNamed:#"mapannotation.png"]];
Now have to remove image when you drag a map view and add image which looks like an annotation. And after completion of that add annotation and remove image from Map View.
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
NSLog(#"Region will changed...");
[self.mapView removeAnnotation:self.fixAnnotation];
[self.mapView addSubview:self.annotationImage];
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
NSLog(#"Region did changed...");
[self.annotationImage removeFromSuperview];
CLLocationCoordinate2D centre = [mapView centerCoordinate];
self.fixAnnotation.coordinate = centre;
[self.mapView addAnnotation:self.fixAnnotation];
}
Its not an map annotation overlay, its a normal UIImageView which has been placed over MKMapView, and it always used to get the lat-long for the center point of the map.
Hope this would be an easy way to achieve your goal.
#Kampai has added the same code for you.
How do I make map balloons when a marker is being touched or tapped in iOS?
to put it simply i want my application's map feature to be able to popup a map balloon to display certain information on the location where the marker is located.
I'm using google maps since i've heard that for now it is more accurate than the Mapkit in iOS.
the image below is my objective in this question:
If you want this custom map balloons for your markers, while using google maps sdk for ios, you can use the function
- (UIView *) mapView: (GMSMapView *) mapView markerInfoWindow: (GMSMarker *) marker
This allows you to display a custom info window for a marker instead of the default infowindow. You need to design a view as shown in your picture , assign the required values and return the view in this function. Please check this earlier post to see an example of making a custom infowindow . You can adjust how the infowindow is located with respect to the marker, by setting value for the property marker.infoWindowAnchor
To create a balloon like annotation , you need to override MKMapView's method
- (MKAnnotationView *)viewForAnnotation:(id < MKAnnotation >)annotation
Like this:
- (MKAnnotationView *)viewForAnnotation:(id < MKAnnotation >)annotation{
static NSString* annotationIdentifier = #"Identifier";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
if(annotationView)
return annotationView;
else
{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
// here we say NO to call out, it means the default popover type view wont open when you click on an //annotation and you can override to show your custom popover
annotationView.canShowCallout = NO;
// here you need to give a ballon image
annotationView.image = [UIImage imageNamed:[NSString stringWithFormat:#"balloon.png"]];
return annotationView;
}
return nil;
}
To create the custom popover/ view that opens when you tap on an annotation , you need to override MKMapViewDelegate's method
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
Here in this method you woould need to create a Popover Controller and present it.
Hi guys I am working with Google maps sdk now, I kinda have two doubts:
Callouts:
How to customize callouts, I had a hard time trying to figure out a way to customize the existing stuff but could not. I found this though.
GMSMarkers:
I want to center the marker in the map view i.e, the marker should be in a particular position that I set and also the current zoom level should also be maintained.
I did the marker centering but now I am showing a callout from the marker and I want to center the callout to be centered.
Thanks in advance.
For the GMSMarker question: You have to create a camera that points to the marker position and then set the mapview camera to it
somemarker = [[GMSMarker alloc] init];
somemarker.position = CLLocationCoordinate2DMake(lat, lng);
somemarker.map = mapView;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:somemarker.position.latitude longitude:somemarker.position.longitude zoom:13];
[mapView setCamera:camera];
You can see my SO answer here that shows how to do custom infowindows (callouts).
You can do this by using this code -
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker {
NSLog(#"the post title is :%# %#",marker.userData,marker.title);
CustomInfoWindow *view = [[[NSBundle mainBundle] loadNibNamed:#"CustomInfoWindow" owner:self options:nil] objectAtIndex:0]; // Your Created Custom View XIB.
UILabel *theLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 50,150, 50)];// Create a Custom Label and add it on the custom view.
theLabel.text = marker.title; // marker.title is the title of pin.
[view addSubview:theLabel];
return view;
}
I use a MKMapView to show my current location , I found that when i am doing nothing ,it will take me about 15+ seconds to see the blue circle and point in the map view ,but if i move the map after the map view is start to locating ,the blue circle and point will show immediately (will dont need 5 seconds now) ,what 's the diffrence between them ? can I short the time to show blue circle in coding ? thanks alot
i create the map
self.runMapView = [[[MKMapView alloc] initWithFrame:self.bounds] autorelease];
self.runMapView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.runMapView.showsUserLocation = YES;
runMapView.delegate = self;
and then :
- (void)mapView:(MKMapView *)mapView_ didUpdateUserLocation:(MKUserLocation *)userLocation
{
if (loc2 == nil)//loc 2 is the ivar i used to track my first location
{
if (CLLocationCoordinate2DIsValid(userLocation.location.coordinate))
{
self.loc2 = userLocation.location;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 2000, 2000);
[runMapView setRegion:region];
}
}
}
and i add some polylineview to the map,and when i add the mapview to the view ctrl 's view at start ,the mapview 's alpha is set to 0(because i have a button to decide show or hide mapview),i dont know if the map update location in back can cause this problem?
Create one variable for location manager,
You need to update location just below the mapview initialize like this:
self.runMapView = [[[MKMapView alloc] initWithFrame:self.bounds] autorelease];
self.runMapView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.runMapView.showsUserLocation = YES;
self.runMapView.delegate = self;
[self.locationManager startUpdatingLocation];