Skip to content

Instantly share code, notes, and snippets.

@tadeha
Last active July 20, 2022 14:47
Show Gist options
  • Save tadeha/0d7df23394c3310fbfa6da4b9efc4360 to your computer and use it in GitHub Desktop.
Save tadeha/0d7df23394c3310fbfa6da4b9efc4360 to your computer and use it in GitHub Desktop.
🗺Map View with Bottom Components for each Marker // Using Google Maps and written in Swift 5
//
// MapViewController.swift
//
// Created by Tadeh Alexani on 7/14/19.
// Copyright © 2019 Tadeh Alexani. All rights reserved.
//
import UIKit
import GoogleMaps
class MapViewController: UIViewController {
@IBOutlet weak var mapView: GMSMapView!
@IBOutlet weak var collectionView: UICollectionView!
var locationManager = CLLocationManager()
var zoomLevel: Float = 15.0
var restaurants = [Restaurant]()
override func viewDidLoad() {
super.viewDidLoad()
// Initialize the location manager.
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 50
locationManager.startUpdatingLocation()
locationManager.delegate = self
mapView.delegate = self
//mapView.settings.myLocationButton = true
mapView.isMyLocationEnabled = true
mapView.isHidden = true
// If the value of this property is true, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls.
collectionView.isPagingEnabled = true
}
}
// Delegates to handle events for the location manager.
extension MapViewController: CLLocationManagerDelegate {
// Handle incoming location events.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location: CLLocation = locations.last!
// Define getList Function in your class to fill your sample array (here restaurants) and then don't forget to RELOAD COLLECTION VIEW
getListOfRestaurants(with: location)
let camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude,
longitude: location.coordinate.longitude,
zoom: zoomLevel)
if mapView.isHidden {
mapView.isHidden = false
mapView.camera = camera
} else {
mapView.animate(to: camera)
}
}
// Handle authorization for the location manager.
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted:
print("Location access was restricted.")
case .denied:
print("User denied access to location.")
// Display the map using the default location.
mapView.isHidden = false
case .notDetermined:
print("Location status not determined.")
case .authorizedAlways: fallthrough
case .authorizedWhenInUse:
print("Location status is OK.")
@unknown default:
fatalError()
}
}
// Handle location manager errors.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.stopUpdatingLocation()
print("Error: \(error)")
}
}
extension MapViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return restaurants.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mapDetailCell",
for: indexPath) as? MapRestaurantDetailCollectionViewCell else {
fatalError("The dequeued cell is not an instance of mapDetailCell.")
}
let restaurant = restaurants[indexPath.row]
cell.nameLabel.text = restaurant.name
cell.addressLabel.text = restaurant.address
ImageHelper.shared.loadImage(withUrl: restaurant.logo, imgView: cell.logoImgView)
// Add location marker on the map
let marker = GMSMarker(position: CLLocationCoordinate2D(latitude: restaurant.lat, longitude: restaurant.long))
marker.userData = ["slug": restaurant.slug, "indexPath": indexPath]
marker.icon = ImageHelper.shared.imageWithImage(image: UIImage(named: "detail-pin-icon")!, scaledToSize: CGSize(width: 22, height: 31))
marker.map = self.mapView
return cell
}
// Handle when user scrolls the horizontal collection view (here change the map camera position to the selected restaurant marker)
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
var visibleRect = CGRect()
visibleRect.origin = collectionView.contentOffset
visibleRect.size = collectionView.bounds.size
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
guard let indexPath = collectionView.indexPathForItem(at: visiblePoint) else { return }
let restaurant = restaurants[indexPath.row]
let camera = GMSCameraPosition.camera(withLatitude: restaurant.lat,
longitude: restaurant.long,
zoom: zoomLevel)
mapView.animate(to: camera)
}
}
extension MapViewController: GMSMapViewDelegate {
// Handle when user tapped on a marker (here scroll to the selected item on the collection view)
@objc(mapView:didTapMarker:) func mapView(_: GMSMapView, didTap marker: GMSMarker) -> Bool {
guard let userData = marker.userData as? [String:Any] else { return false }
guard let indexPath = userData["indexPath"] as? IndexPath else { return false }
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .right)
return true
}
}
@mehdin13
Copy link

Great.👌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment