Skill Level Beginner
- [Instructor] Most map applications let you select a point on a map. However, touching a map, usually, is only for moving a map around. You might want to get a coordinate at a user's tap. In this tip, I'll show you how to get the coordinate, and place a marker there. Download the starter file, and you'll find an application for displaying a map of Twin Rivers, Wisconsin. This is one of three contenders. The others being Evanston, Illinois, and Ithaca, New York, for the first ice cream sundae.
Run the code, and you get a map. Stop the app. There's a few steps for converting a touch into a coordinate. First you need tap. And react to the tap. Second, you get the coordinate of the tap, and the system of the view. Finally, you get a map coordinate that corresponds to the view's coordinate. To get the touch, use a tap gesture recognizer. Go to the story board. And type gesture into the filter.
You'll see several gestures. Some of these are continuous, like pinches, and some like the tap, are discrete. Drag a tap gesture recognizer into the scene. You'll see it does not become part of the view, but becomes part of the view controller. You can control the nature of the taps in the attributes. A double tap on a map is a zoom gesture. So keep the default taps of one and one here.
Close up the attributes in specter, open the assistant editor, and make an action from the gesture recognizer to he view controller. So I'll control drag from tap gesture recognizer. So just above clear annotations. And I'm going to call this tap gesture. I'm going to make it an action. Of view I tap gesture recognizer.
And connect. And I can go ahead and close the assistant editor. And I'll open my view controller now. Give myself lots of space. 'Cause we won't be going back and forth anymore. And once we switch over the view controller and find the tap gesture method, several things about tap gestures. They are gesture recognizers, which fire for all kinds of reasons. So you have to pick the one you want to do your action on.
So type this. If sender.state equals. State is the property that says what kind of action our tap gesture is doing. And I'm going to put a dot here, and you'll see all the different kinds of state we can have. The one we want is an ended. And the reason we want that is it's the last point we've touched. And that's a static point. Anything else, our fingers are vibrating a little bit, and we're not getting an accurate tap.
So we want to do it on the ended, which is the same thing actually as a button, which does it on when you leave your finger from the button. And then inside of the F, we now have our tap. So I'm going to put in let locationInView equal. And this will be a CG point, which will be in the view that we're looking at. So it's going to take the tap and say, okay, this tap exists in this view at this point.
And to do that, we use the sender, which is our tap gesture. And I'm going to do location. In view. So this requires a view. You have two choices here. You can use the sender's view, which would be the entire tappable area, or the map view. For a reason I'll explain in a minute, I'm going to use the map view here.
So location and view returns a CG point in the view. Now I'm going to make that CG point into a map coordinate of type CL location coordinate 2D. There's another method for that, which comes from MapKit, which as you see here, I've already imported. And that MapKit method is convert. So add this. Let tapped coordinate equals mapView.convert.
And you'll see there's several different kinds of converts here. And the one we're interested in is point, CG point, toCoordinateFrom, UIView. And so this will take our point, location and view, and then find that coordinate in a UIView. In this case, what we'll be using is the mapView, which is why I want to match this mapView with up here, so that we're using the same coordinate system.
Now, in a map like we're doing, which is a full page, that's not too big of a deal. But if you had two maps on the same page, that could cause some problems. Or, if you did the full view, and you did a mapView in these two, you might get inaccurate results. So try to keep those two the same. So I'll get the CL coordinate, location 2D from this, which matches the tapped coordinate. With that coordinate, I'll make an annotation with a method I already created called addAnnotation, you can see on the bottom here.
So I'm just going to do addAnnotation. And coordinate is tapped coordinate. Now we've got our simulator set from iPhone A plus, and that's all we need to do here. So go ahead and build and run this. Tap on the map. And a marker appears. Tap again, and more markers appear.
Now, tap outside the view, let's say over here, and nothing happens. And clear will clear out all the pins I already have. So giving taps to map coordinates takes just a few steps, but it's not difficult. Your biggest challenge is to make sure you use the right view for getting the tap, and the map coordinates.