Creating a map options view
The built-in AWFMapOptionsViewController
provides a quick and easy way to control the map layers and various options for an AWFWeatherMap
instance. However, you may want to provide a custom map options view within your own applications instead of the built-in version.
The basic approach is to use an UITableView
to display the available options, which can then be divided into sections as needed based on any particular grouping of options. This is what the built-in AWFMapOptionsViewController
automatically does for you.
The following is a basic implementation of setting up a custom map options view using a UITableView
, which can then be customized further using custom UITableViewCell
instances as required by your application. Since the example below posts a notification when weather layers are ready to be added and/or removed based on the option selections, you'll need to observe this notification where appropriate so you can then add and remove the layers on your weather map instance.
import UIKit
import AerisMapKit
class MapOptionsViewController: UIViewController {
static let LayersDidChange = NSNotification.Name("MapLayersDidChange")
let tableView = UITableView()
// array to store the supported layer options to display in the table view
var layerOptions = [AWFMapLayer]()
// currently active layers on the map, set before this controller is presented
var activeLayers = [AWFMapLayer]()
// keep track of layer selection/deselection so we know what needs to be added/removed
// when this controller is dismissed
var layersToAdd = [AWFMapLayer]()
var layersToRemove = [AWFMapLayer]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.dataSource = self
tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "LayerCell")
view.addSubview(tableView)
NSLayoutConstraint.activate([tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.leftAnchor.constraint(equalTo: view.leftAnchor),
tableView.rightAnchor.constraint(equalTo: view.rightAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)])
// array of layer options to display in the table view
layerOptions = [.radar, .advisories]
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.post(name: MapOptionsViewController.LayersDidChange, object: self, userInfo: ["add": layersToAdd, "remove": layersToRemove])
}
fileprivate func isLayerActive(layer: AWFMapLayer) -> Bool {
return (activeLayers.contains(layer) && layersToRemove.contains(layer) == false) || layersToAdd.contains(layer)
}
}
extension MapOptionsViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return layerOptions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "LayerCell", for: indexPath)
let layer = layerOptions[indexPath.row]
let selected = isLayerActive(layer: layer)
cell.textLabel?.text = AWFWeatherLayer.name(forLayerType: layer)
if selected {
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
} else {
tableView.deselectRow(at: indexPath, animated: false)
}
return cell
}
}
extension MapOptionsViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let layer = layerOptions[indexPath.row]
if !layersToAdd.contains(layer) {
layersToAdd.append(layer)
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let layer = layerOptions[indexPath.row]
if let index = layersToRemove.index(of: layer) {
layersToRemove.remove(at: index)
}
}
}