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 take care of our problems like not making us come back to ViewController, ListViewController, and adding the data automatically to our TableView, and then we're going to customize our pin views so that we can add a navigation button through our pin views, okay? So, in order to add the data to our TableView, we're going to use the notification center in the ViewController, like we did before in the previous section. Remember, we can use notification center here in order to send the message to the whole app then we can observe this message from anywhere we want in the app so that we can trigger an action. So, let's go for it. Let's go NotificationCenter.default.post and choose the one with a name and the object, and actually we don't even need an object. So, we're going to call this nil afterwards but for right now, I'm going to open parentheses and in the row value, I'm going to say 'newPlace' and the object will be nil, okay? I just want to send a newPlace message to the whole app so that I can come over my ListViewController and then observe this message and if I see the newPlace message then I can trigger some function. And the function that I will be triggering is to getting data from the Core Data. And in here, I can just say navigationController.popViewController and the animated will be true. So, this will bring me back to my ListViewController and in the ListViewController, we have to check for this message but remember we cannot do that in the viewDidLoad because viewDidLoad only gets called once, so I'm going to go for viewWillAppear as usual. And in here, I'm going to go for NotificationCenter.default and rather than posting, I'm just observing this time. So, I'm going to choose this addObserver which has the parameters of observer, selector, name and object. So, observer will be self and selector will be a selector function, okay? I'm going to give getData function. We already have that in here, all I have to do is add add objective seen here and in the name, of course, I'm going to go for addPlace. This has to be exactly the same as we have written before, so newPlace, okay? And the object will be nil. So, this will observe this message whenever it gets displayed to the user. So, whenever it sees this it will trigger the getData function. So, let's go and try one. Let's change the location. Okay, let's go for 48. So, let's say, okay and let's hit on the add button and I want to come over here to Notre Dame cathedral, okay? And zoom in a little bit and for the name, I'm going to go for Notre Dame and for the Notes, let's just say cathedral, okay? And then we can hold on here for three seconds, it will add my pin which we are going to customize later on. And here we go. When I say, save, it saves the Notre Dame and we can actually come and look at it later on. So, our app is working as it's supposed to be and all we have to do is just add a navigation button to our pin view so we can call a navigation. When we click on the add button, it still brings us to the current location of the user which is around here. So far so good. Now, I believe it's working fine. We can see the selected places. Its centers around the selected place, it doesn't take us to any other place. So, it's definitely stopping the location manager and it's not updating the location, so, we are seeing everything. So, now we have to customize this pin to add a button to the right side of the pin so that when we click on it, it will bring a navigation to the selected place. So, how do we do that? Of course, we have a player built in function for that as well. We have a function for customizing the pins, we can use that function in order to design our pin so that if we want a button on the pin, we can add it. If we want to display any message in the pin, we can display it. So, let me show you how it goes. Let me go under this location manager, so if you write viewFor annotation, that's the one we're looking for, okay?viewFor annotation. So, as you can see it asks us to return an MKAnnotationView and it gives us an annotation. So, we're going to use all of these parameters to create our own pinView. So, what we're going to do? We're going to create a variable here, okay? And this will be our pinView, so let me create this 'var' and we're going to drive this from the mapView. And if you say, mapView.dequeue, okay?dequeueReusableAnnotationView, so that's the way we want with identifier. We don't even need the for, you can just go for the first one. We just want the one with identifier. So, this will ask us an identifier and you can write whatever you want to write in here, let's create an identifier string in here because it will ask us for a couple of times. Let's say that this is 'reuseId' for example, and I'm just going to call this my annotation and if you want you can call this anything you want as long as you just reuse it anytime you're asked for ID. I'm going to optionally cast this as MKAnnotationView. I'm not MKAnnotationView, MKPinAnnotationView, okay? And it will ask me for to return an MKAnnotationView but I'm just going to return an MKPinAnnotationView and don't worry, that's okay. If you say return pinView right now, even though pinView is an MKPinAnnotationView it will be okay because they are practically the same thing, okay? Now, we have created our pinView but we need to make sure to set this up before we go on and return this pinView, okay? First thing to check if this pinView is an user location pinView and if it's the case, I'm not going to return anything because I don't want to pin my user's location. So, a way to do that is just say if a notation is MKUserAnnotation and by annotation, I'm referring the annotation that is given to me within the function, okay? And as you can see MKUserLocation defines the user's location. So, if that's the case, I'm just going to return nil, I don't want to pinpoint anything regarding my user's location. I just want to show a pin in the selected place, okay? So, I'm just going to do this here. If that's the case, I'm returning nil and if that's not the case, I'm returning my pinView. And under pinView, let's go for it. Let's change the pinView. First, I'm going to check to see if pinView is nil. If pinView is nil, I'm going to assign some values to it. And if that's not the case, I'm just going to return the annotation that is given to me. So, what do I mean? I'm just going to create my pinView as MKPinAnnotationView and it will ask me for an annotation and that's the annotation that I want to give, okay? And the reuse identifier will be the one that I have created before, it doesn't matter as long as you use the same reuse identifier in both of these pinViews, okay? If pinView is nil, I'm creating a new one as you can see and in here I can say, canShowCallout. So, this is a boolean indicating whether the annotation view is able to display an extra information so that's what we want. We're going to display an extra button on the right hand side of our pinView. So, that will be true and in here actually, we can change the other attributes of the pinView itself. For example, we can change the color of the pinView if we want like, you can just go over in here say, pinView.tintColor, is UIcolor.black, red, blue, whatever you want, okay? So, after doing that, I believe we should not waste time or changing any other pinView attributes like color or something, okay? We can go ahead to add our button to the right hand side of our pinView and in order to do that, I just have to create button in here with code. So, you know how to do that, you can just say let button is a UIButton, okay? If you open parenthesis it will ask you for a type and in here if you hit enter and hit that, you will see some other types, I want detailDisclosure. So, you will see, what I mean by detailDisclosure. It's kind of an I, I can standing for information. And if you say, pinView.rightCalloutAccessoryView. You can make it equal to button. So, rightCalloutAccessoryView is the way that we are looking for. Else, if pinView is not even nil then it means that I can just come over here and say pinView.annotation is the annotation that is given me within the function. So, that's it. I know it's kind of complicated for you right now because it's the first time you're seeing this. If you just take a look at the code, it's not even complicated. We're just creating a pinView and here you go. Now, we have our pinView in the Notre Dame cathedral. So, if you click on this pinView, it will display this rightCalloutAccessoryView and it's a disclosure button, detailDisclosure button, so we can click on this. Of course, nothing happens right now because we haven't written it yet but this is the detailDisclosure button and we have written all of these codes in order to add this button to our pinViews and in order to show you exactly how to customize a pinView if you need one any day. So, let's stop here and within the next lecture we're going to add navigation when we click on that button.
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.