The course is part of this learning path
This course explores maps and how we can integrate them into our apps. We'll leverage map functions like finding the user location, showing the user's location on the map, and choosing a location on the map to get its coordinates. And in order to do that, we're going to be focusing on an app called Travel Book. We're going to integrate Core Data in this Travel Book as well so that we can re-practice what we have learned in the previous section.
This course is designed for anyone who wants to:
- Learn about iOS development and coding
- Move into a career as an iOS developer
- Master Swift skills
To get the most out of this course, you should have some basic knowledge of iOS.
Hi. Within this lecture, we're going to see how to pin the map. However, before we do that, let's recap the previous lecture because we have learned a lot. As you might remember, in the location we have chosen another location. We changed the user's location and the map got updated. So, it means that whenever I change my location, we're going to get that location in the didUpdateLocations functions and we're going to display it on the map so that when user walks or changes his location, it will be reflected on the map because we're zooming in that region, okay?
And again in the previous lecture we have learned about something called span and it defines the width and height of the current map view. So, with 0.1, we get some view like that. So, let me run from the beginning actually and we can see 0.1 in an exact way. So, it starts like this. It's kind of zoomed out I believe. So, let's try 0.05 as I said before, and it will give us a zoomed in, more zoomed in view, I believe it will be much better. And now as you can see it's much better and we can actually try for 0.03 as well, but I believe this is optimal. So, I'm going to leave it as it is, I suggest you try with other numbers and experience on with yourself.
So, next thing to do is just to add a gesture recognizer here so that when user taps on one of these map locations, it will get pinned. So, we're going to use the old gesture recognizer in order to do that, but we're not going to use the same old UI tap gesture recognizer because we want to long press on here for like three seconds in order to tag this. If we make it with a tap gesture recognizer, then it won't be very good because every time I touch on map it will just tag the map, it will just drop a pin, and that's not what I want. I want to choose a specific location in which I can long press, like hold for three seconds and then I can see the tagged location. So, let me show you how it's done.
We're going to create a gesture recognizer as usual, okay? I'm going to say let gestureRecognizer and rather than saying UITapGestureRecognizer, I'm just going to go for UILongPressGestureRecognizer. So, this is again a gesture recognizer that looks for long press gestures, okay? And don't worry, we're going to set it up as usual. So, we're just going to have to specify a target which is self and of course we're just going to have to specify a selector function like we used to do before. So, it's not different than UITapGestureRecognizer.
So, I'm going to say objc function, and in here we can just something like we can just say something like chooseLocation, okay? And that's it, that's how you create gesture recognizers with UILongPressGestureRecognizer type. But here we're going to do something different. Rather than just saying this is going to be a function, I' m just going to give a gestureRecognizer input here as well, because we're going to need that gestureRecognizer type to work upon. You'll know what I mean. Let's write that and I will explain later on.
So, I'm going to call this gestureRecognizer and it's going to be a type of UILongPressGestureRecognizer, okay? Like this. So, choose the UILongGestureRecognizer, and if I now come over here to this action and say chooseLocation, okay? It will bring me as a view like that and I can double click on this, and that's how I assign this selector to my gestureRecognizer. So, why did I even do that? Under chooseLocation function, I have to use the properties of the gestureRecognizer, like what? Like I'm just going to see if gestureRecognizer has begun. So, for example, if I say gestureRecognizer. I can reach the properties I can reach the attributes of that gestureRecognizer, right?
So, I can just control to see if gestureRecognizer state is okay == .began, .began or cancelled or changed or failed. If I want to see the current state of the gestureRecognizer now I can reach and use it. So, when I do that it connects me to the UILongPressGestureRecognizer that my user will be doing on the map so I can see if it's failed or canceled or began. I'm just going to control the began by the way, so if it began then I'm going to perform my operations, but I'm just telling you for this like an example, okay? That's why I have given this gestureRecognizer, UILongPressGestureRecognizer in here. And as usual I'm going to close down this here, and I'm going to come over here and say mapView.addGestureRecognizer, it will ask me for my gestureRecognizer and I'm going to give it one. But before we go on and do that, we have to set minimum duration of that gestureRecognizer because it's a LongPressGestureRecognizer, and we're going to specify how long.
So, whether we want something like five seconds or three seconds, in order to do that, say .minimumPressDuration and go for a three. And we're going for three because if we make it like one it will be too short. We can easily capture the other types of the user by mistake. If we make it something like five, it will be too long this time. So, user will think there's something wrong I'm pressing over here and nothing happens. So, I'm going to go for a three. We generally use three but you can experience with other numbers as well.
So, after that, under choose location, I'm going to go ahead and actually control if this state is began. So, once my gestureRecognizer begins, I can get the clicked coordinates from that point, okay? So, we're going to see how to do it. Don't worry, first of all, let's check if gestureRecognizer.state is actually equal to began. So, let's say that .state == .began. So, it means that has received touched objects as you can see in the description. So, once we do that, once it's began it means that it received something called touchedPoints. And I'm going to create that touchedPoints with a variable, I'm going to assign it to be a variable because we're going to get the coordinates out of that touchedPoints. In order to do that, you have to say gestureRecognizer.location, okay?
So, this gives us a point in some view and of course we're going to say self.mapView in here because we're going to use that location from map view. And again this gestureRecognizer gives us a touchedPoint. So, it means that wherever user touched on that view, okay? And we can create a coordinate with that touchedPoint, and in order to do that, you have to say self.mapView. and convert. And we're looking for converting a point to a coordinate, okay? So, we're looking for this one. So, we're converting a point and we're converting it from a view.
So, we have a lot of options here, please try to choose the right one, point toCoordinateFrom. So, as you can see this converts a point in the specified view's coordinate system to a map view. So, I'm going to say touchedPoint for for the point, and we're going to say self.mapView here one more time, and again, this will give us the touchedPoint of the user, and this will give us the coordinates of that touchedPoint. Next thing I'm going to create the pin that we have been talking about, and it's called annotation. And it's type of MK pinpoint annotation actually.
So, if you come over here you can just say MKPointAnnotation, as you can see this will create the object for us. When you create an annotation, you have to give it some coordinates, okay? Annotation.coordinates and we have this coordinate, right? touchedCoordinates. And you can give some titles to your annotations as well. I'm going to say annotation.title "New Place or New Annotation." And I'm just doing this for an example so that you will see what is a title, what is a subtitle, and how they are displayed in the map, okay?
So, I'm just going to go for Travel Book here so that you can see why we're using titles, why we're using subtitles. And then you can just call the mapView and say .addAnnotation and choose the annotation that we have created. So, let me run this and if this works, I'm going to explain it one more time. Don't worry if it's got too complicated for you. Now, let's zoom in into Eifel Tower and I'm going to hit over here and hold for three seconds, and here you go. Here we have the first annotation. So, as you can see it says that new annotation, and under the new annotation we have the Travel Book subtitle.
So, let me zoom in so we can see it better. As you can see this is the title and this is the subtitle that I have been creating so far. So, we're going to use this annotation in our Travel Book and we're going to display the name and the comment of the user not of the user in that annotation with title and subtitle. So, what did we do? We created this gestureRecognizer, and once it begins it gives something called touchedPoint. And we can get this by saying that gestureRecognizer.location and we convert that point to a coordinate and we give these coordinates to the annotation that we have created. You're seeing this for the first time and it might seem complicated, but once you actually get used to it, you will see it's actually very easy compared to what we have been learning so far. So, let's stop here and continue within the next lecture.
Atil is an instructor at Bogazici University, where he graduated back in 2010. He is also co-founder of Academy Club, which provides training, and Pera Games, which operates in the mobile gaming industry.