139 lines
4.5 KiB
Swift
139 lines
4.5 KiB
Swift
//
|
|
// RealtimeAlertViewController.swift
|
|
// Earthquake Network
|
|
//
|
|
// Created by Andrea Busi on 15/06/22.
|
|
// Copyright © 2022 Earthquake Network. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import MapKit
|
|
|
|
|
|
class RealtimeAlertViewController: UIViewController {
|
|
|
|
@objc var onClose: () -> Void = {}
|
|
|
|
// MARK: - Internal
|
|
|
|
private let containerView = RealtimeAlertContainerView()
|
|
private var notificationView: RealtimeAlertView {
|
|
containerView.alertView
|
|
}
|
|
/// Manage the wave animation on the map and the countdown label
|
|
private lazy var animator: MapSeismicWaveAnimator = {
|
|
let animator = MapSeismicWaveAnimator(
|
|
realtimeAlert: realtimeAlert,
|
|
mapView: notificationView.mapView,
|
|
waveTimeLabel: notificationView.waveTimeLabel
|
|
)
|
|
return animator
|
|
}()
|
|
/// Alert to display
|
|
private let realtimeAlert: EQNRealtimePushNotification
|
|
|
|
// MARK: - Init
|
|
|
|
@objc
|
|
init(notification: EQNRealtimePushNotification) {
|
|
self.realtimeAlert = notification
|
|
super.init(nibName: nil, bundle: nil)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
deinit {
|
|
// importante togliere il delegato, altrimenti causa crash
|
|
notificationView.mapView.delegate = nil
|
|
}
|
|
|
|
// MARK: - View Lifecycle
|
|
|
|
override func loadView() {
|
|
view = containerView
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
configureUI()
|
|
updateUI()
|
|
|
|
animator.start()
|
|
}
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
|
|
containerView.startBackgroundAnimation()
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private func configureUI() {
|
|
notificationView.mapView.delegate = self
|
|
|
|
notificationView.closeButton.addTarget(self, action: #selector(onTapClose(_:)), for: .touchUpInside)
|
|
|
|
// configure color for animation
|
|
containerView.animationColor = realtimeAlert.relativeIntensityColor
|
|
}
|
|
|
|
private func updateUI() {
|
|
notificationView.descriptionLabel.text = realtimeAlert.title
|
|
|
|
// update title with distance from earthquake
|
|
let distanceRound = Int(round(realtimeAlert.distanceFromUser() / 1_000))
|
|
notificationView.descriptionLabel.text = (notificationView.descriptionLabel.text ?? "")
|
|
+ ".\n"
|
|
+ String(format: NSLocalizedString("official_distance", comment: ""), distanceRound)
|
|
|
|
notificationView.intensityLabel.text = realtimeAlert.displayBody
|
|
notificationView.intensityLabel.textColor = realtimeAlert.relativeIntensityColor
|
|
|
|
// center map on the earthquake coordinate
|
|
let span = MKCoordinateSpan(latitudeDelta: 10.5, longitudeDelta: 10.5)
|
|
let region = MKCoordinateRegion(center: realtimeAlert.coordinate.coordinate, span: span)
|
|
notificationView.mapView.setCenter(realtimeAlert.coordinate.coordinate, animated: false)
|
|
notificationView.mapView.setRegion(region, animated: true)
|
|
|
|
// aggiungiamo annotation con epicentro sisma
|
|
notificationView.addMapAnnotation(center: realtimeAlert.coordinate.coordinate, intensity: realtimeAlert.intensity)
|
|
|
|
// aggiungiamo un segmento tra la posizione del sisma e quella dell'utente
|
|
if let lastPosition = EQNUser.default().lastPosition {
|
|
notificationView.addMapLine(coordinates: [realtimeAlert.coordinate.coordinate, lastPosition.coordinate])
|
|
}
|
|
}
|
|
|
|
// MARK: - Action
|
|
|
|
@objc private func onTapClose(_ sender: UIButton) {
|
|
// stoppiamo animazione e countdown
|
|
animator.stop()
|
|
|
|
onClose()
|
|
dismiss(animated: true)
|
|
}
|
|
}
|
|
|
|
extension RealtimeAlertViewController: MKMapViewDelegate {
|
|
|
|
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
|
|
animator.getOverlayRenderer(for: overlay) ?? MKOverlayRenderer(overlay: overlay)
|
|
}
|
|
|
|
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
|
|
guard let annotation = annotation as? EQNMapAnnotationPastquake else {
|
|
return nil
|
|
}
|
|
|
|
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: EQNCustomAnnotationView.SingleLineIdentifier, for: annotation) as! EQNCustomAnnotationView
|
|
annotationView.image = annotation.image
|
|
annotationView.title = annotation.title
|
|
return annotationView
|
|
}
|
|
}
|