Hey guys this is Caleb with slopes dot com.
And in this video we're going to add a UI tap gesture recognizers that we can double tap on our map
view drop a pen and we're also going to set up the function to animate the pin dropping.
We're going to implement one of the delegate methods from M-K map view delegate that allows us to customize
the appearance of those pins.
We're going to set it to be orange which is cool just like our interface is a little bit orange.
And let's get into it now.
So pull open that X code project just like that.
And we're going to start by actually creating a function that will create our tap gesture.
So to do that go ahead and beneath you did load write a function called phunk add double tap.
Whoa.
Double tap.
And inside of here we're going to create a constant called Double tap and it's going to be you tap gesture
recognizer it's going to be an instance of that.
Now you tap just your recognizer needs a target and an action.
So the target is going to be self and the action is going to be a function that we have not yet created.
So we need to actually create that function first and we're going to do it in M-K map view delegate
it's going to be a custom function.
So go ahead and write phunk drop pin.
And this is where we will drop the pin on the map.
We're not going to do it yet but we're going to use that in order to set up our tap gesture recognizer
so to do this we need to type the pound sign selector.
Or as I like to call it hash tag selector.
And then inside of the parentheses we're going to just call drop pin because that's the name of the
function that we're using.
Ok super easy but you're going to notice that it gives us some errors.
It's going to say argument of hash tag selector refers to instance method drop and that is not exposed
to Objective C.
All we need to do is just add at obey C for objective c and basically that's going to fix that problem
for us.
You'll notice it added that little there little thingy there at the front which basically just exposes
this function to Objective-C.
I tap just recognize your needs that that's fine.
What we need to do now is to configure the settings of our tap gesture by typing double tap number of
taps required and it's a double tap.
That means we need two taps to get this to work as well it's not going to work unless we conform to
the wire tap gesture delegate or you gesture recognizer delegate.
So go ahead and type double tap.
Delegate equals self.
But if we try to build this now you'll notice that saying does not cannot assign it to you I gesture
recognize or delegate.
And that's because we are not yet inheriting from that delegate.
So let's do that now.
Go ahead.
Up at the top of your class go ahead and type you a gesture recognize or delegate.
And now if we build it you'll notice that error goes away because now the two are linked.
The double tap delegate here is going to be able to utilize map b c as its delegate.
Pretty cool.
Now the last thing we need to do this tap gesture is worthless unless we add it to a certain view.
So in order to do that we're going to type a map you add gesture recognizer and we're going to pass
in double tap.
OK.
So now whenever we call this function we're adding a tap gesture recognizer to the map that allows us
to double tap it and you know what I think.
Let's go ahead and let's set it up so that as soon as the view loads the double tap is added.
All right.
Very cool.
And you know what.
Just for fun remember.
As soon as the double tap happens it's going to call drop pin.
So let's go ahead and let's print the pin was dropped.
Obviously it's not going to drop a pin but we'll just see if our double tap is working.
So I'm going to build this to an iPhone 7.
So go ahead and build and run.
Let's let's try it out.
Let's see how we're doing.
And let's see if our.
I guess we don't need the 7 plus.
Can I get rid of it.
Let's see.
Well we can minimize it.
That's fine.
All right cool so let's always allow it to use our location.
You'll see that will zoom in and let's see if we double click popped up something hey pin was dropped
pin was dropped.
Double click pin was dropped.
Click click click click.
All right cool so our tap gesture is working exactly as we wanted it to.
That's awesome news.
Very very good.
So now we can actually get into dropping a pin using our cool drop in function.
So let's do that.
Let's go ahead and get rid of that boiler plate junk and what we're going to do is we are first going
to go ahead and we're going to create a touchpoint.
OK.
And a touchpoint is going to be used to basically convert where we touch on the map to the exact coordinate
that is being shown on the map where we touched.
So to create a touch point go ahead and just type let and touch point
equals and you know what.
This is where we actually need to change the way our function works now drop pin does not take any parameters
but we need it to.
It needs information from our you I tap gesture recognizers so to do that we're actually going to pass
in a sender of you I tap gesture recognizer.
Now that means we also need to change our function up here.
Right here drop in and to do that just go ahead and call it again drop in.
And this time it's going to use ascender.
Now the coolest thing is that when we use this with a selector it's going to pass in our UI tap gesture
recognizer into this function.
So now where is it.
Yeah.
Now this sender that came in we're going to be able to access where we touched on the screen we can
get the exact point where we touched so to do that.
Go ahead and type sender and we're going to type location in you view.
Now the view of course is the map view when we use this it's going to print out our touchpoint So let's
try that.
Print touchpoint.
OK let's build and run and let's see what it prints out to the terminal or do the console rather let's
give it a shot.
Rigaud double tap and look at that.
It prints out the exact coordinates not GPS coordinates but on the screen if I get up close to the top
here I don't know if it'll work oh yeah because it's not the map.
But this remember is 70.
So if I click here it should be about 70.
Seventy one point five for the y value.
Very very cool.
So it looks like it's working its converting where we tap into a touch point and now we're going to
do is we're going to convert that touchpoint into a GPS coordinate so go ahead and type let touch.
Coordinate equals map view convert and you're going to notice that there's a lot of options here.
We need to convert a C.G. point and we need to convert it to a coordinate from the map view.
So let's find that to whoops not C-g recked sorry convert point from view.
No that's not right.
We need to convert it to coordinate whereas that to coordinate that is all right.
So convert this point to a co-ordinate from the map view.
Easy as that so passen the touchpoint as our point and the view is going to be the map view.
So this is going to now convert it to GPS coordinates.
This is incredibly useful for us because we can pass this then later into the flicker you the flicker
API and it's going to let us download images from that specific location where we drop the pin.
OK so now what we're going to do is we're going to pass that coordinate into one of those little pins
that drops down on the map view.
And so in order to do that we need to create a custom subclass of M-K annotation that is the class that
we need to use.
And let's go ahead and go on the View folder and let's create a new file.
Ok it's going to be a swift file and we're going to call this drop a bull pen.
Press Enter to save it.
And now let's create a class called drop a weapon.
All right.
And you know what.
Before we go any further we need to import UI kit.
And we also need to import a map kit.
Now this class is going to inherit from both an object and M.K. annotation.
So go ahead and do that and a subject and M.K. annotation.
Now that's just something you need to know.
If you create a custom pin on a map if you've seen my ride sharing course you know that we do this we
create a custom pin with a nice little our own little graphic if you want to do that it needs to inherit
from an object and connotation that's just part of how it works on the map.
So we need to create two different variables that we're going to use in this annotation.
One of them is going to be to hold the coordinate of the annotation and the other is going to be for
an identifier.
This helps us to identify a certain pin later on.
And so to begin we're going to go ahead and type var coordinate that's going to be of type C-L location
coordinate to D and the identifier is going to be var identifier of type string.
Now we need to initialize these as you might expect.
So go ahead and type init.
Not override in it innit.
And then of course coordinate coordinate of type C-L location coordinate to D and the identifier of
type string.
OK.
And now we're going to set the coordinate to be equal to coordinate.
When we initialize it then we're going to type identifier self identifier so we set the one for class
equal to the identifier we pass in at initialization.
Now at the bottom we need to call Super Dome in it and that's going to allow us to use this as an initializer
for our custom pin.
The only thing is that the coordinate cannot be properly set unless it is a dynamic variable.
OK.
Now dynamic variables are able to be modified the way that we need to to create these and connotations.
So with this class created we now can create the annotation to drop on our map.
So go ahead and head back into map Visi And what we're going to do is we're going to create an instance
of drop of a pin.
So we're going to go ahead and type let annotation equals drop a pin and we're going to initialize it
with a coordinate and an identifier.
So the coordinate of course is touch coordinate we just made that and our identifier we're just going
to call this drop a pin.
OK so we're going to use that later to view the pin on the screen you'll see why.
Or you'll see how I mean.
And OK so we have our annotation.
This is an M-K annotation and it's going to drop as a nice pretty little pin.
But the issue is that this is no good unless we add it to the map view.
So go ahead and type map you add annotation and drop in annotation can now it'll show on the map view.
Now the only thing we need to do is we need to set it so that the map moves over and center this pin
because it doesn't center the pin It just doesn't look as cool.
And so to do that we're basically going to use similar code to center map on user location.
We're going to create a coordinate region and we're going to set the map to show that region.
So go ahead and type let coordinate region equals M.K. coordinate region make with distance the center
coordinate of course is going to be touch coordinate latitudinal meters is going to be the same as above.
Region radius times too because we don't want it to like zoom in or zoom out or do anything we want
it to stay about the same height over the map region radius times 2.0.
That's going to give us the same exact region.
And now we're going to call map view that set region coordinate region and animate will be true.
Now whenever we tap on the map it's going to drop a pin and it'll zoom zoom but it'll pan over to exactly
where we dropped it.
Let's go give it a shot.
Gordon BuildOn run this.
And let's go see if it worked.
Let's give it a try.
OK.
That looks pretty good.
Let's double click and let's see if it drops a opin.
Hey look at that.
It dropped a pin.
And beyond that it actually yeah I really like that it centers.
Look at that.
Now there is a problem though is that whenever we drop a pin the old one stays and we don't want that.
We want the next pin to show and the old pin to erase.
So what we're going to do is we're going to quickly write a function called remove pin that's going
to wipe all the pins off the map and just add the new one and we'll call that right before we drop a
pin.
So let's add that below we'll call that phunk remove pin.
And we're going to basically just cycle through all of the annotations in the map view and remove them
all which is OK because we only want it to show one pin at a time.
So to do that type for annotation in map view annotations we're going to go ahead and type map view
remove annotation and pass in that annotation.
So now what we're going to do is in droppin before we add a pin we're going to go ahead and we're going
to call remove pin.
All right and you know what you might be thinking well what if there are no pins cause an issue.
That's not true because this blue dot is an annotation that's added by default it will always be there.
And so it's OK if we call this because it's actually going to remove it.
But it is exempt from removing this one because it's always shown when the location is being used so
build and run.
Let's go see if it properly removes our pin and adds a new one and then we'll call this video quits.
We zoom in we add a pin that looks good.
Yes look at that it removes it.
It zooms to the next one and we can still center our map if we want.
This is looking amazing.
Awesome guys.
So this is great.
In the next video we're going to change this pin so that we can modify the color we don't want it to
be red.
We want it instead to be orange to match our application.
So head over to the next video and we'll set up that custom view.
Now.