iOS/Sources/App/Settings/Eureka/EurekaLocationRow.swift

114 lines
3.9 KiB
Swift

import Eureka
import Foundation
import MapKit
import UIKit
// MARK: LocationRow
class HACircle: MKCircle {
var type: String = "zone"
}
public final class LocationRow: Row<PushSelectorCell<CLLocation>>, RowType {
public required init(tag: String?) {
super.init(tag: tag)
displayValueFor = {
guard let location = $0 else { return "" }
let fmt = NumberFormatter()
fmt.maximumFractionDigits = 4
fmt.minimumFractionDigits = 4
let latitude = fmt.string(from: NSNumber(value: location.coordinate.latitude))!
let longitude = fmt.string(from: NSNumber(value: location.coordinate.longitude))!
return "\(latitude), \(longitude)"
}
}
override public func customDidSelect() {
super.customDidSelect()
guard !isDisabled else { return }
let vc = MapViewController { _ in }
vc.row = self
cell.formViewController()?.navigationController?.pushViewController(vc, animated: true)
vc.onDismissCallback = { _ in
vc.navigationController?.popViewController(animated: true)
}
}
}
public class MapViewController: UIViewController, TypedRowControllerType, MKMapViewDelegate {
public var row: RowOf<CLLocation>!
/// A closure to be called when the controller disappears.
public var onDismissCallback: ((UIViewController) -> Void)?
lazy var mapView: MKMapView = {
let v = MKMapView(frame: view.bounds)
v.autoresizingMask = UIView.AutoresizingMask.flexibleWidth.union(UIView.AutoresizingMask.flexibleHeight)
return v
}()
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nil, bundle: nil)
}
public convenience init(_ callback: ((UIViewController) -> Void)?) {
self.init(nibName: nil, bundle: nil)
self.onDismissCallback = callback
}
override public func viewDidLoad() {
super.viewDidLoad()
view.addSubview(mapView)
mapView.delegate = self
mapView.showsUserLocation = true
if let value = row.value {
let dropPin = MKPointAnnotation()
dropPin.coordinate = value.coordinate
mapView.addAnnotation(dropPin)
let region = MKCoordinateRegion(
center: value.coordinate,
latitudinalMeters: 400,
longitudinalMeters: 400
)
mapView.setRegion(region, animated: true)
if value.horizontalAccuracy != 0 {
let circle = HACircle(center: value.coordinate, radius: value.horizontalAccuracy)
circle.type = "device"
mapView.addOverlay(circle)
}
}
let fmt = NumberFormatter()
fmt.maximumFractionDigits = 4
fmt.minimumFractionDigits = 4
let latitude = fmt.string(from: NSNumber(value: mapView.centerCoordinate.latitude))!
let longitude = fmt.string(from: NSNumber(value: mapView.centerCoordinate.longitude))!
title = "\(latitude), \(longitude)"
}
public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let overlay = overlay as? HACircle {
let circle = MKCircleRenderer(overlay: overlay)
if overlay.type == "zone" {
circle.strokeColor = UIColor.red
circle.fillColor = UIColor.red.withAlphaComponent(0.1)
circle.lineWidth = 1
circle.lineDashPattern = [2, 5]
} else if overlay.type == "device" {
circle.strokeColor = UIColor.blue
circle.fillColor = UIColor.blue.withAlphaComponent(0.1)
circle.lineWidth = 1
}
return circle
} else {
return MKOverlayRenderer(overlay: overlay)
}
}
}