551 lines
24 KiB
Swift
551 lines
24 KiB
Swift
//
|
|
// SeismicNetworkTableViewCell.swift
|
|
// Earthquake Network
|
|
//
|
|
// Created by Busi Andrea on 22/09/2020.
|
|
// Copyright © 2020 Earthquake Network. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import MapKit
|
|
import CoreLocation
|
|
import Shogun
|
|
|
|
protocol SeismicNetworkTableViewCellDelegate: AnyObject {
|
|
func seismicNetworkCellDidTapShare(_ cell: SeismicNetworkTableViewCell)
|
|
func seismicNetworkCellDidTapMap(_ cell: SeismicNetworkTableViewCell)
|
|
func seismicNetworkCellDidTapMapDetail(_ cell: SeismicNetworkTableViewCell)
|
|
func seismicNetworkCellDidTapIntensityMapDetail(_ cell: SeismicNetworkTableViewCell)
|
|
func seismicNetworkCellDidTapCalendar(_ cell: SeismicNetworkTableViewCell)
|
|
func seismicNetworkCellDidTapSettings(_ cell: SeismicNetworkTableViewCell)
|
|
func seismicNetworkCellDidTapClose(_ cell: SeismicNetworkTableViewCell)
|
|
}
|
|
|
|
class SeismicNetworkTableViewCell: UITableViewCell {
|
|
|
|
static let Identifier = "SeismicNetworkTableViewCell"
|
|
|
|
/// Available informations to display inside the cell
|
|
enum InformationType: Int {
|
|
case preliminary
|
|
case time
|
|
case distance
|
|
case coordinate
|
|
case population
|
|
case realtimeSmartphones
|
|
case reportUsers
|
|
case intensityMap
|
|
case buttons
|
|
}
|
|
|
|
/// Available cell type
|
|
enum DisplayType {
|
|
/// Compact view
|
|
case normal
|
|
/// Cell with map visible
|
|
case mapExpanded
|
|
}
|
|
|
|
/// Delegate
|
|
weak var delegate: SeismicNetworkTableViewCellDelegate?
|
|
|
|
// MARK: - Internal
|
|
|
|
private static let DefaultButtonHeight: CGFloat = 34.0
|
|
private static let VerticalSpacingDefault: CGFloat = 6.0
|
|
private static let VerticalSpacingSmall: CGFloat = 2.0
|
|
|
|
/// Seismic to show
|
|
private var seismic: EQNSisma?
|
|
private(set) var displayType = DisplayType.normal
|
|
private var informationTypes = [InformationType]()
|
|
private var isPushSelected = false
|
|
|
|
// MARK: - UI Components
|
|
|
|
private lazy var containerView: UIView = {
|
|
let view = UIView(frame: .zero)
|
|
view.translatesAutoresizingMaskIntoConstraints = false
|
|
view.backgroundColor = .white
|
|
view.clipsToBounds = true
|
|
return view
|
|
}()
|
|
|
|
private lazy var gradientView: UIImageView = {
|
|
// Per gestire il gradiente, utilizziamo una image view in cui inseriamo un'immagine
|
|
// creata ad-hoc con il gradiente desiderato.
|
|
// Le prove fatte utilizzando una view normale sono fallite perchè al momento di
|
|
// disegnare la view non abbiamo le misure corrette.
|
|
let view = UIImageView(frame: .zero)
|
|
view.translatesAutoresizingMaskIntoConstraints = false
|
|
view.contentMode = .scaleToFill
|
|
return view
|
|
}()
|
|
|
|
private lazy var placeLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = UIFont.preferredFont(forTextStyle: .title2, weight: .semibold)
|
|
label.numberOfLines = 3
|
|
return label
|
|
}()
|
|
|
|
private lazy var shareButton: UIButton = {
|
|
let button = UIButton(type: .custom)
|
|
button.translatesAutoresizingMaskIntoConstraints = false
|
|
button.setImage(UIImage(named: "share_icon"), for: .normal)
|
|
button.addTarget(self, action: #selector(shareTapped(_:)), for: .touchUpInside)
|
|
return button
|
|
}()
|
|
|
|
private lazy var networkLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.textAlignment = .right
|
|
label.font = .preferredFont(forTextStyle: .subheadline)
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var magnitudeLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = UIFont.preferredFont(forTextStyle: .largeTitle)
|
|
label.textColor = .red
|
|
return label
|
|
}()
|
|
|
|
private lazy var depthLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var timeLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var distanceLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var coordinateLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var populationLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var smartphonesLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.numberOfLines = 0
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.textAlignment = .center
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var alertsLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.numberOfLines = 0
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.textAlignment = .center
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var mapView: MKMapView = {
|
|
let mapView = MKMapView(frame: .zero)
|
|
mapView.translatesAutoresizingMaskIntoConstraints = false
|
|
mapView.isScrollEnabled = false
|
|
mapView.isZoomEnabled = false
|
|
mapView.layer.cornerRadius = AppTheme.shared.cardCornerRadius
|
|
mapView.layer.masksToBounds = true
|
|
return mapView
|
|
}()
|
|
|
|
// MARK: - Init
|
|
|
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
|
setupUI()
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
super.init(coder: coder)
|
|
setupUI()
|
|
}
|
|
|
|
// MARK: - View Lifecycle
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
|
|
containerView.eqn_applyShadowAndRoundedCorners()
|
|
gradientView.eqn_applyRoundedCorners()
|
|
}
|
|
|
|
// MARK: - Setup
|
|
|
|
private func setupUI() {
|
|
selectionStyle = .default
|
|
backgroundColor = .clear
|
|
|
|
// container view
|
|
contentView.addSubview(containerView)
|
|
containerView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 4.0).isActive = true
|
|
containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8.0).isActive = true
|
|
containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0).isActive = true
|
|
containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4.0).isActive = true
|
|
|
|
containerView.addSubview(gradientView)
|
|
gradientView.constraint(to: containerView)
|
|
|
|
// this variable is used to keep track of the previous view, in order to attach proper constraints
|
|
var previousView: UIView = containerView
|
|
|
|
// preliminary banner on top of the cell
|
|
if informationTypes.contains(.preliminary) {
|
|
let preliminaryLabel = UILabel()
|
|
preliminaryLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
preliminaryLabel.text = NSLocalizedString("official_prelimiary", comment: "").uppercased()
|
|
preliminaryLabel.textAlignment = .center
|
|
preliminaryLabel.backgroundColor = .red
|
|
preliminaryLabel.textColor = .yellow
|
|
|
|
containerView.addSubview(preliminaryLabel)
|
|
preliminaryLabel.heightAnchor.constraint(equalToConstant: 30.0).isActive = true
|
|
preliminaryLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
|
|
preliminaryLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
|
|
preliminaryLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
|
|
|
|
previousView = preliminaryLabel
|
|
}
|
|
|
|
containerView.addSubview(placeLabel)
|
|
containerView.addSubview(shareButton)
|
|
|
|
let titleTopAnchor = previousView == containerView ? containerView.layoutMarginsGuide.topAnchor : previousView.bottomAnchor
|
|
placeLabel.topAnchor.constraint(equalTo: titleTopAnchor).isActive = true
|
|
placeLabel.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
|
placeLabel.trailingAnchor.constraint(equalTo: shareButton.leadingAnchor, constant: .cardPadding.negative).isActive = true
|
|
|
|
shareButton.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
|
shareButton.centerYAnchor.constraint(equalTo: placeLabel.centerYAnchor).isActive = true
|
|
shareButton.heightAnchor.constraint(equalToConstant: 24.0).isActive = true
|
|
shareButton.heightAnchor.constraint(equalTo: shareButton.widthAnchor, multiplier: 1.0).isActive = true
|
|
|
|
let separator1 = addSeparator(constraintTo: placeLabel.bottomAnchor)
|
|
let informationsLeadingAnchor = separator1.leadingAnchor
|
|
let informationsTrailingAnchor = separator1.trailingAnchor
|
|
|
|
// magnitude information
|
|
containerView.addSubview(magnitudeLabel)
|
|
magnitudeLabel.topAnchor.constraint(equalTo: separator1.bottomAnchor, constant: Self.VerticalSpacingSmall).isActive = true
|
|
magnitudeLabel.leadingAnchor.constraint(equalTo: informationsLeadingAnchor, constant: 14).isActive = true
|
|
|
|
if !informationTypes.contains(.preliminary) {
|
|
containerView.addSubview(depthLabel)
|
|
depthLabel.lastBaselineAnchor.constraint(equalTo: magnitudeLabel.lastBaselineAnchor).isActive = true
|
|
depthLabel.leadingAnchor.constraint(equalTo: magnitudeLabel.trailingAnchor, constant: 16).isActive = true
|
|
}
|
|
|
|
// informations
|
|
let stackViewInformations = UIStackView()
|
|
stackViewInformations.translatesAutoresizingMaskIntoConstraints = false
|
|
stackViewInformations.axis = .vertical
|
|
stackViewInformations.distribution = .equalSpacing
|
|
stackViewInformations.spacing = 4
|
|
|
|
if informationTypes.contains(.time) {
|
|
stackViewInformations.addArrangedSubview(timeLabel)
|
|
}
|
|
if informationTypes.contains(.distance) {
|
|
stackViewInformations.addArrangedSubview(distanceLabel)
|
|
}
|
|
if informationTypes.contains(.coordinate) {
|
|
stackViewInformations.addArrangedSubview(coordinateLabel)
|
|
}
|
|
if informationTypes.contains(.population) {
|
|
stackViewInformations.addArrangedSubview(populationLabel)
|
|
}
|
|
|
|
containerView.addSubview(stackViewInformations)
|
|
stackViewInformations.topAnchor.constraint(equalTo: magnitudeLabel.bottomAnchor, constant: Self.VerticalSpacingSmall).isActive = true
|
|
stackViewInformations.leadingAnchor.constraint(equalTo: informationsLeadingAnchor, constant: 14).isActive = true
|
|
stackViewInformations.trailingAnchor.constraint(equalTo: informationsTrailingAnchor, constant: -14).isActive = true
|
|
previousView = stackViewInformations
|
|
|
|
// network
|
|
containerView.addSubview(networkLabel)
|
|
networkLabel.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.VerticalSpacingSmall).isActive = true
|
|
networkLabel.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
|
networkLabel.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
|
previousView = networkLabel
|
|
|
|
if informationTypes.contains(.realtimeSmartphones) || informationTypes.contains(.reportUsers) || informationTypes.contains(.intensityMap) {
|
|
let separator2 = addSeparator(constraintTo: previousView.bottomAnchor, constanst: Self.VerticalSpacingSmall)
|
|
|
|
let stackViewReports = UIStackView()
|
|
stackViewReports.translatesAutoresizingMaskIntoConstraints = false
|
|
stackViewReports.axis = .vertical
|
|
stackViewReports.distribution = .equalSpacing
|
|
stackViewReports.alignment = .center
|
|
stackViewReports.spacing = Self.VerticalSpacingDefault
|
|
|
|
if informationTypes.contains(.realtimeSmartphones) {
|
|
stackViewReports.addArrangedSubview(smartphonesLabel)
|
|
}
|
|
if informationTypes.contains(.reportUsers) {
|
|
stackViewReports.addArrangedSubview(alertsLabel)
|
|
}
|
|
if informationTypes.contains(.intensityMap) {
|
|
let buttonMap = EQNRoundedButton.make(title: "🎯 \(NSLocalizedString("shakemap", comment: ""))", target: self, action: #selector(intensityMapTapped(_:)))
|
|
stackViewReports.addArrangedSubview(buttonMap)
|
|
buttonMap.heightAnchor.constraint(equalToConstant: Self.DefaultButtonHeight).isActive = true
|
|
buttonMap.leadingAnchor.constraint(equalTo: stackViewReports.leadingAnchor).isActive = true
|
|
buttonMap.trailingAnchor.constraint(equalTo: stackViewReports.trailingAnchor).isActive = true
|
|
}
|
|
|
|
containerView.addSubview(stackViewReports)
|
|
stackViewReports.topAnchor.constraint(equalTo: separator2.bottomAnchor, constant: Self.VerticalSpacingDefault).isActive = true
|
|
stackViewReports.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
|
stackViewReports.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
|
|
|
previousView = stackViewReports
|
|
}
|
|
|
|
if informationTypes.contains(.buttons) {
|
|
let separator3 = addSeparator(constraintTo: previousView.bottomAnchor)
|
|
previousView = separator3
|
|
|
|
// buttons
|
|
let stackViewButtons = UIStackView()
|
|
stackViewButtons.translatesAutoresizingMaskIntoConstraints = false
|
|
stackViewButtons.axis = .horizontal
|
|
stackViewButtons.distribution = .fillEqually
|
|
stackViewButtons.spacing = 8
|
|
|
|
let buttonMap = EQNRoundedButton.make(title: "🗺", target: self, action: #selector(mapTapped(_:)))
|
|
stackViewButtons.addArrangedSubview(buttonMap)
|
|
let buttonCalendar = EQNRoundedButton.make(title: "📆", target: self, action: #selector(calendarTapped(_:)))
|
|
stackViewButtons.addArrangedSubview(buttonCalendar)
|
|
let buttonSettings = EQNRoundedButton.make(title: "🔧", target: self, action: #selector(settingsTapped(_:)))
|
|
stackViewButtons.addArrangedSubview(buttonSettings)
|
|
|
|
containerView.addSubview(stackViewButtons)
|
|
stackViewButtons.heightAnchor.constraint(equalToConstant: Self.DefaultButtonHeight).isActive = true
|
|
stackViewButtons.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.VerticalSpacingDefault).isActive = true
|
|
stackViewButtons.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
|
stackViewButtons.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
|
|
|
previousView = stackViewButtons
|
|
}
|
|
|
|
if displayType == .mapExpanded {
|
|
containerView.addSubview(mapView)
|
|
mapView.heightAnchor.constraint(equalToConstant: 140.0).isActive = true
|
|
mapView.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.VerticalSpacingDefault).isActive = true
|
|
mapView.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
|
mapView.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
|
|
|
previousView = mapView
|
|
}
|
|
|
|
if (displayType == .mapExpanded) {
|
|
let buttonClose = EQNRoundedButton.make(title: NSLocalizedString("official_close", comment: "").uppercased(), target: self, action: #selector(closeTapped(_:)))
|
|
|
|
containerView.addSubview(buttonClose)
|
|
buttonClose.heightAnchor.constraint(equalToConstant: Self.DefaultButtonHeight).isActive = true
|
|
buttonClose.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.VerticalSpacingDefault).isActive = true
|
|
buttonClose.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
|
buttonClose.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
|
buttonClose.bottomAnchor.constraint(equalTo: containerView.layoutMarginsGuide.bottomAnchor).isActive = true
|
|
}
|
|
else {
|
|
previousView.bottomAnchor.constraint(equalTo: containerView.layoutMarginsGuide.bottomAnchor).isActive = true
|
|
}
|
|
|
|
containerView.eqn_applyShadowAndRoundedCorners()
|
|
gradientView.eqn_applyRoundedCorners()
|
|
}
|
|
|
|
private func recreateUI() {
|
|
// remove all subviews and recreate the required components
|
|
containerView.subviews.forEach({ $0.removeFromSuperview() })
|
|
setupUI()
|
|
}
|
|
|
|
private func updateUI() {
|
|
guard let seismic = seismic else { return }
|
|
|
|
let viewModel = SeismicNetworkViewModel(seismic: seismic)
|
|
|
|
gradientView.image = .gradient(from: viewModel.colors.startColor, to: viewModel.colors.endColor, with: .init(origin: .zero, size: .init(width: 500, height: 1)))
|
|
|
|
// update seismic data
|
|
placeLabel.text = viewModel.place
|
|
placeLabel.textColor = isPushSelected ? AppTheme.Colors.pureBlue : AppTheme.shared.cardTextColor
|
|
networkLabel.text = String(format: NSLocalizedString("official_provider", comment: ""), viewModel.network)
|
|
magnitudeLabel.textColor = viewModel.colors.textColor
|
|
magnitudeLabel.text = viewModel.magnitude
|
|
depthLabel.text = viewModel.depth
|
|
timeLabel.text = "🕗 \(viewModel.time)"
|
|
distanceLabel.text = "📐 \(viewModel.distance)"
|
|
coordinateLabel.text = "🌍 \(viewModel.coordinate)"
|
|
|
|
// evaluate population string
|
|
populationLabel.text = "👥 \(viewModel.population)"
|
|
let populationIsRed = seismic.population100km >= 1_000_000 || seismic.userDistance <= 250
|
|
populationLabel.textColor = populationIsRed ? AppTheme.Colors.red : .black
|
|
|
|
if !viewModel.smartphones.isEmpty {
|
|
smartphonesLabel.text = "🚨 \(viewModel.smartphones)"
|
|
}
|
|
if !viewModel.users.isEmpty {
|
|
alertsLabel.text = "⚠️ \(viewModel.users)"
|
|
}
|
|
|
|
|
|
if displayType == .mapExpanded {
|
|
// zoom based on population involved
|
|
let longitudeSpan = mapSpanLongitude(population: seismic.population100km)
|
|
let span = MKCoordinateSpan(latitudeDelta: longitudeSpan * 1.2, longitudeDelta: longitudeSpan)
|
|
let region = MKCoordinateRegion(center: seismic.coordinate.coordinate, span: span)
|
|
mapView.setCenter(seismic.coordinate.coordinate, animated: false)
|
|
mapView.setRegion(region, animated: false)
|
|
|
|
// add a pin on the center
|
|
let annotation = MKPointAnnotation()
|
|
annotation.coordinate = seismic.coordinate.coordinate
|
|
annotation.title = ""
|
|
mapView.addAnnotation(annotation)
|
|
|
|
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(mapDetailTapped(_:)))
|
|
mapView.addGestureRecognizer(tapRecognizer)
|
|
}
|
|
}
|
|
|
|
// MARK: - Public
|
|
|
|
/// Configure the cell to display a seismic
|
|
/// - Parameters:
|
|
/// - seismic: Seismic to display
|
|
/// - type: Type of cell
|
|
/// - informations: Informations to show
|
|
public func configure(
|
|
with seismic: EQNSisma,
|
|
type: DisplayType,
|
|
informations: [InformationType],
|
|
isPushSelected: Bool
|
|
) {
|
|
self.seismic = seismic
|
|
self.displayType = type
|
|
self.informationTypes = informations
|
|
self.isPushSelected = isPushSelected
|
|
|
|
if !informations.contains(.time) {
|
|
self.informationTypes += [.time]
|
|
}
|
|
|
|
if seismic.preliminary.intValue > 0 && !informations.contains(.preliminary) {
|
|
self.informationTypes += [.preliminary]
|
|
}
|
|
if seismic.smartphoneNumber.intValue > 0 && !informations.contains(.realtimeSmartphones) {
|
|
self.informationTypes += [.realtimeSmartphones]
|
|
}
|
|
if seismic.userNumber.intValue > 0 && !informations.contains(.reportUsers) {
|
|
self.informationTypes += [.reportUsers]
|
|
}
|
|
if seismic.isoCode == "0" && informations.contains(.intensityMap) {
|
|
self.informationTypes.removeAll { $0 == .intensityMap }
|
|
}
|
|
|
|
recreateUI()
|
|
updateUI()
|
|
}
|
|
|
|
// MARK: - Actions
|
|
|
|
@objc func shareTapped(_ sender: UIButton) {
|
|
delegate?.seismicNetworkCellDidTapShare(self)
|
|
}
|
|
|
|
@objc func mapTapped(_ sender: UIButton) {
|
|
if displayType != .mapExpanded {
|
|
delegate?.seismicNetworkCellDidTapMap(self)
|
|
}
|
|
}
|
|
|
|
@objc func calendarTapped(_ sender: UIButton) {
|
|
delegate?.seismicNetworkCellDidTapCalendar(self)
|
|
}
|
|
|
|
@objc func settingsTapped(_ sender: UIButton) {
|
|
delegate?.seismicNetworkCellDidTapSettings(self)
|
|
}
|
|
|
|
@objc func closeTapped(_ sender: UIButton) {
|
|
delegate?.seismicNetworkCellDidTapClose(self)
|
|
}
|
|
|
|
@objc func mapDetailTapped(_ sender: Any) {
|
|
delegate?.seismicNetworkCellDidTapMapDetail(self)
|
|
}
|
|
|
|
@objc func intensityMapTapped(_ sender: Any) {
|
|
delegate?.seismicNetworkCellDidTapIntensityMapDetail(self)
|
|
}
|
|
|
|
// MARK: - Helpers
|
|
|
|
@discardableResult
|
|
private func addSeparator(constraintTo: NSLayoutYAxisAnchor, constanst: CGFloat = 8.0) -> UIView {
|
|
let separator = UIView()
|
|
separator.translatesAutoresizingMaskIntoConstraints = false
|
|
separator.backgroundColor = .lightGray
|
|
containerView.addSubview(separator)
|
|
|
|
separator.topAnchor.constraint(equalTo: constraintTo, constant: constanst).isActive = true
|
|
separator.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
|
separator.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
|
separator.heightAnchor.constraint(equalToConstant: 1.0).isActive = true
|
|
|
|
return separator
|
|
}
|
|
|
|
/// Determines the zoom for the map, based on the involved population
|
|
private func mapSpanLongitude(population: Double) -> CLLocationDegrees {
|
|
var zoom: CLLocationDegrees = 1
|
|
if population > 1_000_000 {
|
|
zoom = 1
|
|
} else if population < 500 {
|
|
zoom = 24
|
|
} else {
|
|
zoom = 6
|
|
}
|
|
return zoom
|
|
}
|
|
}
|