Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Form like callout, touch events forwarding. #33

Closed
foFox opened this issue Feb 26, 2013 · 6 comments
Closed

Form like callout, touch events forwarding. #33

foFox opened this issue Feb 26, 2013 · 6 comments

Comments

@foFox
Copy link

foFox commented Feb 26, 2013

What I am trying to achieve is essentially a simple callout, which is actually a form where user enters some data. There are two text fields, one segmented control and one button. So the user taps the pin, callout appears, user types in the data required, presses a button and "it just works", except it doesn't really. Seems like map view interferes with taps quite heavily not allowing me to do pretty much anything when the callout it tapped. And since the default action, when user taps the callout, is to make it disappear, that is all I get.

I have a custom subclass of MKPinAnnotation called PlaceCreatorAnnotation

http://pastebin.com/f9N5KTA7

So I read the header in the sample project, which says that I should override hitTest in order to make things behave correctly in terms of touch delivery. As you can see I changed self.calloutView to self.calloutView.contentView. Why? In case of just self.calloutView the result is pretty much the same, whenever I click on a callout, map view treats it as deselection, and dismisses the callout. If on another hand I go for self.calloutView.calloutView, then it kinda seems to work. Why kinda? Well, button and segmented control at least change their appearance on tap, I don't know if they send the action yet, but they get something. What is really interesting that tap on any of the text views, seems to work for a split second, as I can see the keyboard starting to appear. But after it appears completely, again, for some reason map decides to deselect the pin, dismiss the keyboard and the callout.

How do I create the callout ?

Code :

http://pastebin.com/ZiQ5BGik

I don't know how to make it format properly on github.

So the question is how do I make sure that map does not decide to unselect the annotation. Inside the call back methods like did select annotation view, did deselect annotation view, its too late to determine where the user tapped on the screen, so I can't really make the right decision from there.

@nfarina
Copy link
Owner

nfarina commented Feb 27, 2013

OK, so this was pretty tricky but I think I figured it out. On iOS 6, MKMapView uses a UIGestureRecognizer to figure out when you've tapped on the map. For some reason, when you attempt to click a UITextField in the callout, this causes the gesture recognizer to fire and the map view to think that you've clicked outside the pin and wish to dismiss the callout.

I've just pushed an example to the master branch that demonstrates how to work around this. The trick is to subclass MKMapView and override the gesture recognizer delegate to swallow touches from UIControl subclasses. Just uncomment the three lines that create a UITextField to see it in action.

Hope this works for you!

@foFox
Copy link
Author

foFox commented Feb 27, 2013

Still no luck, could the problem be caused by AutoLayout and/or using much larger view than standard callout created from a nib which also uses auto layout? As well I also have a long press attached to the map.

I noticed that I in that overridden delegate method for gesture recogniser, the touch.view is always MKAnnotationContainerView

I did some printing in the debugger.

http://pastebin.com/GCjd58p5

why does the callout view have negative x/y?

@foFox
Copy link
Author

foFox commented Feb 27, 2013

Ok, so main the difference between how your sample code works and what happens when I tap the map in code, is precisely, what is under touch.view. In your case it is indeed what I clicked, button/textfield/etc. In my code its ALWAYS that MKAnnotationContainerView no matter what I click. The weird part, I am pretty much not doing anything else than whats in the sample project.

@nfarina
Copy link
Owner

nfarina commented Feb 27, 2013

Hm, that's weird. So how did you fix it?

@foFox
Copy link
Author

foFox commented Feb 27, 2013

http://pastebin.com/vLuhB8dx

Turns out that altering -pointInside:(CGPoint)point withEvent:(UIEvent *)event inside SMCalloutView by adding
contentViews pointsInside method to be also checked, does the job perfectly. I am not sure if I removed this line before by myself. But it works now.

@nfarina
Copy link
Owner

nfarina commented Feb 27, 2013

Yeah, I should have explicitly mentioned that, but that was one of the things I fixed when looking into this originally. Glad that did the trick!

@nfarina nfarina closed this as completed Feb 27, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants