// // 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 } }