Files
eqn.ios/Sources/Earthquake Network/UI/EQNBaseContainerTableViewCell.swift
T

160 lines
6.3 KiB
Swift

//
// EQNBaseContainerTableViewCell.swift
// Earthquake Network
//
// Created by Andrea Busi on 14/06/24.
// Copyright © 2024 Earthquake Network. All rights reserved.
//
import UIKit
import Shogun
extension CGFloat {
fileprivate static let cardVerticalMargin: CGFloat = 4.0
fileprivate static let cardHorizontalMargin: CGFloat = 8.0
/// Padding between the card border and the internal content
static let cardPadding: CGFloat = 8.0
/// Spacing between items inside a card
static let cardVerticalSpacing: CGFloat = 10.0
}
@objc
class EQNBaseContainerTableViewCell: UITableViewCell {
/// Inset to apply to enclosing table view. Used to adjust spacing around the cells (for instance, top space is smaller that the space between the cards)
@objc static let EdgeInsets: UIEdgeInsets = .init(top: CGFloat.cardHorizontalMargin - CGFloat.cardVerticalMargin, left: 0, bottom: 0, right: 0)
// MARK: - UI
private lazy var internalContainerView: UIView = {
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .white
return view
}()
private lazy var chevronView: UIImageView = {
let imageView = UIImageView(image: .init(systemName: "chevron.right"))
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
imageView.tintColor = AppTheme.Colors.lightGray
return imageView
}()
lazy var containerView: UIView = {
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var headerLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
label.font = .preferredFont(forTextStyle: .title2)
label.textColor = AppTheme.shared.cardTextColor
return label
}()
private lazy var emptyTopView: UIView = {
let view = UIView(frame: .zero)
view.backgroundColor = .clear
return view
}()
/// Returns the top view to use to attach descendant constraints
var topView: UIView {
isHeaderVisible ? headerLabel : emptyTopView
}
/// If `true` an header on the top left corner will be visible
var isHeaderVisible: Bool { true }
/// If `true` a right chevron is displayed on right side
var isRightArrowVisbile: Bool { false }
/// Text to display inside the header
var headerText: String { "" }
override var backgroundColor: UIColor? {
set {
internalContainerView.backgroundColor = newValue
}
get {
internalContainerView.backgroundColor
}
}
// MARK: - Init
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
updateUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupUI()
updateUI()
}
// MARK: - View Lifecycle
override func layoutSubviews() {
super.layoutSubviews()
containerView.eqn_applyRoundedCorners()
internalContainerView.eqn_applyShadowAndRoundedCorners()
}
// MARK: - Internal
func setupUI() {
selectionStyle = .default
super.backgroundColor = .clear
contentView.addSubview(internalContainerView)
internalContainerView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: .cardVerticalMargin).isActive = true
internalContainerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: .cardHorizontalMargin.negative).isActive = true
internalContainerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: .cardHorizontalMargin).isActive = true
internalContainerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: .cardVerticalMargin.negative).isActive = true
internalContainerView.addSubview(containerView)
containerView.topAnchor.constraint(equalTo: internalContainerView.topAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: internalContainerView.leadingAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: internalContainerView.bottomAnchor).isActive = true
if isRightArrowVisbile {
contentView.addSubview(chevronView)
chevronView.centerYAnchor.constraint(equalTo: internalContainerView.centerYAnchor).isActive = true
chevronView.trailingAnchor.constraint(equalTo: internalContainerView.trailingAnchor, constant: .cardPadding.negative).isActive = true
chevronView.heightAnchor.constraint(equalToConstant: 24.0).isActive = true
chevronView.widthAnchor.constraint(equalTo: chevronView.heightAnchor).isActive = true
containerView.trailingAnchor.constraint(equalTo: chevronView.leadingAnchor, constant: .cardPadding.negative).isActive = true
} else {
containerView.trailingAnchor.constraint(equalTo: internalContainerView.trailingAnchor).isActive = true
}
if isHeaderVisible {
containerView.addSubview(headerLabel)
headerLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: .cardPadding).isActive = true
headerLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
headerLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
} else {
containerView.addSubview(emptyTopView)
emptyTopView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
emptyTopView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
emptyTopView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
emptyTopView.heightAnchor.constraint(equalToConstant: 0.0).isActive = true
}
}
func updateUI() {
// setup titles, colors and UI stuff here
headerLabel.text = headerText.firstCharacterCapitalized
}
}