14.3. Phase 3: Place Search and Navigate
At this point, we will add a Bottom Search Sheet to find the places around and navigate there.
Setting up the Bottom Search Sheet
First, let's add a search button at the bottom of the Map Screen. Open MapView.swift file, and put the following code to add the search button and its constraints:
//
// MapView.swift
// App14
//
// Created by Sakib Miazi on 6/14/23.
//
import UIKit
import MapKit
class MapView: UIView {
//codes omitted...
var buttonSearch:UIButton!
override init(frame: CGRect) {
//codes omitted...
setupButtonSearch()
initConstraints()
}
//codes omitted...
func setupButtonSearch(){
buttonSearch = UIButton(type: .system)
buttonSearch.setTitle(" Search places... ", for: .normal)
buttonSearch.titleLabel?.font = UIFont.boldSystemFont(ofSize: 24)
buttonSearch.setImage(UIImage(systemName: "magnifyingglass.circle.fill"), for: .normal)
buttonSearch.layer.backgroundColor = UIColor.darkGray.cgColor
buttonSearch.tintColor = .white
buttonSearch.layer.cornerRadius = 10
buttonSearch.layer.shadowOffset = .zero
buttonSearch.layer.shadowRadius = 4
buttonSearch.layer.shadowOpacity = 0.7
buttonSearch.translatesAutoresizingMaskIntoConstraints = false
buttonSearch.isHidden = true
self.addSubview(buttonSearch)
}
func initConstraints(){
NSLayoutConstraint.activate([
//codes omitted...
buttonSearch.bottomAnchor.constraint(equalTo: buttonCurrentLocation.bottomAnchor),
buttonSearch.centerXAnchor.constraint(equalTo: self.safeAreaLayoutGuide.centerXAnchor),
buttonSearch.heightAnchor.constraint(equalTo: buttonCurrentLocation.heightAnchor)
])
}
//codes omitted...
}
Now, let's create the files related to the Bottom Search Sheet in the project: SearchViewController.swift, SearchBottomSheet.swift, SearchTableViewCell.swift, and SearchTableViewManager.swift.

Then we set up the Bottom Search Sheet following the example in .
Bottom Search Sheet
SearchViewController.swift
Let's add the following code to the file:
SearchBottomSheet.swift
Let's add the following code to the file:
SearchTableViewCell.swift
Let's add the following code to the file:
SearchTableViewManager.swift
Let's add the following code to the file:
Displaying the Bottom Search Sheet
We need to add an action to the search button in ViewController. And then display the bottom search sheet.
Let's add the following code in ViewController.swift file:
In the above code:
On lines 25 through 38, we handle the action when the user taps on the search button.
We create the bottom search sheet and embed it in a navigation controller.
Then we define the presentation style, detents, and grabber for the bottom search sheet.
Finally, present the sheet.
If we run the app now:

So, our bottom search sheet is working!
Searching Nearby Places
Here we have to type something on the search bar, and depending on what we type, it should display the list of related places in the search results table view. So, let's open SearchViewController.swift and put in the following code to add a delegate to mapview:
In the above code, on line 13, we declare a delegate variable to the ViewController where the map view is.
Now, let's create a new file named LoadPlaces.swift in the group "Map Screen." 
Let's write the following code in the file:
In the above code:
We import CoreLocation and MapKit libraries to search places.
We extend the ViewController class and define the method
loadPlacesAround()where we take a String parameter namedquery.We use
MKLocalSearchservice from Apple Maps to search for places.On line 16, we create a search request instance.
On line 17, we set the
naturalLanguageQueryof the local search service to the parameterquery.Now, the search request needs a region, right? We won't be searching the whole world. So on line 21, we set the search region to the current map view region. It means I will be looking for places close to the region we see on the map inside the screen.
On lines 24 through 38, we run the search for the places related to the query.
Now, let's open SearchViewController.swift file again and call loadPlacesAround() method when the user type something:
In the above code, on line 18, we call the loadPlacesAround(query: searchText) method of map screen using the delegate. We send the text the user writes on the search bar.
We need to update ViewController.swift file to initialize the delegateToMapView variable. So, let's initialize it as the following code:
In the above code, on line 14, we initialize delegateToMapView variable of the search view controller to self.
Let's run the app.

The results are getting printed in the output area in the above demo. The results are related to the search query "coffee." It fetches all the coffee shops around.
Displaying the search results in the search table view
Now we have the search results in the map screen, so we need to send them back to the search result table view. We will use Notification Center for that. We need to observe the data from the search bottom sheet. We post the notification from the map screen.
Setting an observer from the bottom search sheet
Open SearchViewController.swift file, and put the following code there:
In the above code:
We observe the notification center on lines 20 through 25.
On lines 29 through 32, we define the method for handling the notification received event.
We basically receive an array of map items. Then we have to display them in the table view.
Let's open SearchTableViewManager.swift file and add the following code to display the map items on the cells:
In the above code:
On lines 15 through 17, we set the text of the cell's
labelTitleto the name of the current map item.
Posting notification from Map Screen
Let's open LoadPlaces.swift file, and put the following code there:
In the above code:
On line 15, we initialize the notification center.
On line 43, we post the map items we fetched to the notification center.
Let's run the app again:

Great! We can see the search results!!! Now can we show the place on the map when we select it on the table view?
Code so far
Last updated
Was this helpful?