MKPinAnnotationView disable selection/highlight but not lift and drag - ios

I have a MKPinAnnotationView that I would like to be able to long press and drag around but not tap and select. Sometimes the user will touch just the right way (a short touch on the pin) and the pin will become highlighted (darkens) instead of lifting and dragging. I use the drag to show a magnifying glass so its a bit disruptive when the user touches a pin and drags but nothing happens.
Is there a flag of some kind I can set that prevents the pin from being tap selected and always goes to drag?
I've tried setting the following flags:
annotationView.selected = YES;
annotationView.canShowCallout = NO;
annotationView.highlighted = NO;
Which doesn't prevent the selection. I also tried flipping .selected to NO. I suppose I could override -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view but I'm not sure what I could put in there to bypass the selection. And there is no -(BOOL)shouldSelectAnnotationView... function.

You will most likely have to subclass the pin. Here is the best example I could find. I can not write one as I am not at my computer.
https://github.com/j4n0/callout
Good luck.

Related

Mapkit Callout Accessory Button Activation

I am using MapKit to display a map with many annotations. Each of these annotations has a callout with a UIButton. Most everything works properly, but any time there is an annotation behind the UIButton, it becomes impossible to activate it. I want the UIButton to be activatable regardless of background annotations. Is there a way to ignore the annotations directly behind the callout?
I have found an appropriate workaround to this issue:
(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
[view.superview bringSubviewToFront:view];
}
https://github.com/danielbarela/ios-map-callout-test/issues/1

iOS MapKit: tap in callout touches annotationView that is rendered under the callout

Im my MKMapView, I have a callout of an MKAnnotationView that works fine most of the time and looks like this:
The icons in the callout are buttons.
The problem:
In this case, hidden by the callout, there is an annotation on the map, exactly behind of a button.
When I tap on this button, the AnnotationView behind the button gets the touch event.
When I tap on a button without an annotation behind, the button gets the touch event.
I found this out using the accepted answer of How to debug who is eating my touches in UIKit?
How can I make sure that a touch on a button in the callout doesn't get eaten by an MKAnnotationView that is rendered behind the callout?
There is very much code and at the moment I have no idea which code is relevant to show to you.
Found a solution (I did not find a solution using hitTest):
I now use my own UIView as callout (see Robs comment below the question as a start). That does not change my problem described in the question.
I noticed that I don't have the describd problem when I hit on the buttons in my callout view.
So I put an invisible custom button over all my non interactive labels and textViews. The infoButton shown below does nothing but catching taps. It has the same size as infoStackView below:
This solution should also work if annotationView.detailCalloutAccessoryView is used, as I did when I posed the question.

iOS 11 MKAnnotationView prepareForReuse dismiss the pin view in Map view

what I want to do is when I deselect an pin, the pin view change it's UI back to unselected state(e.g change color of background of the pin)
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
//do something;
XLMapItemAnnotation* mapItem = [self annotationForView:view];
[view prepareForReuse];
}
by having this code, when I run the app in iOS 11, if I deselect a pin, the pin disappear in the map view totally. and if I remove the prepareForReuse, everything would be fine.
and the some code if I run the app in iOS 10, everything is fine, no pin get disappeared.
can sbd give me a hint, what could be wrong?
You should not call -prepareForReuse yourself, it's intended for MapKit to call itself.
As #Tim Johnsen said, -prepareForReuse is intended for MKAnnotationView's reuse mechanism, you should not call it yourself.
In iOS 11, MapKit introduce clustering algorithm for MKAnnotationView(But after some try, I found it cause strange behavior sometimes). In this case, MKAnnotationView.isHidden is set as true by default. So after you invoking -prepareForReuse, MKAnnotationView is hidden.
If you want to change color of the pin, just change pinTintColor property directly, or use a function to reset all properties as needed.

Intercept touches on UIView over GMSMapView

I'm trying to overlay a UIView over a google GMSMapView. The goal is to intercept swipes in order to know when the map is being moved manually. (I know I could check -mapView:willMove: but that gets called regardless of whether the map is moving programmatically or as result of manual touch). I'm programmatically re-centering the map as the position updates--because Google doesn't do it for you like Apple does. Like every map program out there, I want to stop centering on the current position as soon as the user manually moves the map. The only way I can think to capture that occurrence (short of switching to mapkit or waiting for Google to add to the API) is to capture a swipe as it's going past a view laid over the map.
To clarify, my question is how do I lay a view over a google map, make it respond to a swipe and still allow that event to pass through to the GMSMapView?
Both my map and interceptView are sibling children of the main view. interceptView has a gestureRecognizer, is set to opaque, not hidden and userInteractionEnabled = YES. As such the interceptView picks up touch events just fine. But the map underneath doesn't move. If I set interceptView.userInteractionEnabled = NO, the map works fine.
"Passing touches" by overriding touchesBegan and calling GMSMapView's touchesBegan doesn't do anything. And overriding hitTest doesn't seem to be an option because I can't subclass GMSMapView. Has anyone done this? I know there's a lot on here about passing particular events through. I want to process a particular event on two views, one of which is Google's map layer which I can't modify the code of.
mapView:willMove: receives a bool "gesture" which is true if the move was triggered by a user gesture and false if it wasn't. So you can stop re-centering the map only if "gesture" is true. That way you can be sure that the map is being moved manually.
Here is a delegate method check it
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate;
You can intercepte the tap using the GMSMapViewDelegete and implementing this method:
-(void)panoramaView:(GMSPanoramaView *)panoramaView didTap:(CGPoint)point;
Example:
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
CLLocationCoordinate2D panoramaNear = {latitudine,longitudine};
GMSPanoramaView *panoView = [GMSPanoramaView panoramaWithFrame:CGRectZero
nearCoordinate:panoramaNear];
[panoView setDelegate:self];
self.view = panoView;
}
-(void)panoramaView:(GMSPanoramaView *)panoramaView didTap:(CGPoint)point{
NSLog(#"Tap");
}

MKMapKit disalow deselection of callout bubble

I would like to know how I can make sure that a callout bubble can't get deselected on a MKMapView.
Whenever I press on the map (background), this view:
Turns to:
Which I do not want to allow. Yet I do want to keep the callOutButton support.
You could just programmatically select your annotation whenever annotations get deselected (using the corresponding delegate method). If you don't animate this selection then it looks as if the annotation never got deselected in the first place.
Example:
// MKMapView Delegate
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
// Replace "myAnnotation" with whichever annotation you need to remain selected
[mapView selectAnnotation:self.myAnnotation animated:NO];
}
I tried this in a test project and it works fine (it doesn't flicker or anything). It's not exactly disabling deselection but the resulting effect is the same, so it might be a good workaround.

Resources