jsdw_ios/QuickLocation/Section/Explore/FeatureIntroView.swift

228 lines
8.5 KiB
Swift

//
// FeatureIntroView.swift
// QuickLocation
//
import UIKit
struct FeatureIntroItem {
let imageName: String
let accessibilityTitle: String
let aspectRatio: CGFloat
let action: FeatureIntroAction
}
enum FeatureIntroAction {
case signIn
case createBubble
case lockDistract
case pigeonMessage
case searchLocation
case sos
case placeholder
}
final class FeatureIntroView: UIView {
var onTapItem: ((FeatureIntroAction) -> Void)?
private let headerBackgroundView = UIImageView(image: UIImage(named: "Explore/header_bg"))
private let titleContainer = UIStackView()
private let titleLineView = UIView()
private let titleLabel = UILabel()
private let sheetView = UIView()
private let scrollView = UIScrollView()
private let contentView = UIView()
private let gridStack = UIStackView()
private let items: [FeatureIntroItem] = [
FeatureIntroItem(
imageName: "Explore/sign_in_card",
accessibilityTitle: "还在吗",
aspectRatio: 127 / 166,
action: .signIn
),
FeatureIntroItem(
imageName: "Explore/pigeon_message_card",
accessibilityTitle: "飞鸽传书",
aspectRatio: 127 / 166,
action: .pigeonMessage
),
FeatureIntroItem(
imageName: "Explore/lock_distract_card",
accessibilityTitle: "一键锁机",
aspectRatio: 130 / 166,
action: .lockDistract
),
FeatureIntroItem(
imageName: "Explore/bubble_card",
accessibilityTitle: "隐身气泡",
aspectRatio: 130 / 166,
action: .createBubble
),
FeatureIntroItem(
imageName: "Explore/search_location_card",
accessibilityTitle: "查位置",
aspectRatio: 130 / 166,
action: .searchLocation
),
FeatureIntroItem(
imageName: "Explore/sos_card",
accessibilityTitle: "SOS",
aspectRatio: 130 / 166,
action: .sos
)
]
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupUI() {
backgroundColor = .white
headerBackgroundView.contentMode = .scaleAspectFill
headerBackgroundView.clipsToBounds = true
addSubview(headerBackgroundView)
headerBackgroundView.translatesAutoresizingMaskIntoConstraints = false
titleLineView.backgroundColor = UIColor(hexStr: "#253B55")
titleLineView.layer.cornerRadius = 1.5
titleLineView.translatesAutoresizingMaskIntoConstraints = false
titleLabel.text = "一键锁机"
titleLabel.textColor = UIColor(hexStr: "#253B55")
titleLabel.font = FontManager.ziHunBianHei(28)
titleLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
titleContainer.axis = .horizontal
titleContainer.alignment = .center
titleContainer.spacing = 3
titleContainer.addArrangedSubview(titleLineView)
titleContainer.addArrangedSubview(titleLabel)
addSubview(titleContainer)
titleContainer.translatesAutoresizingMaskIntoConstraints = false
sheetView.backgroundColor = .white
sheetView.layer.cornerRadius = 30
sheetView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
sheetView.clipsToBounds = true
addSubview(sheetView)
sheetView.translatesAutoresizingMaskIntoConstraints = false
scrollView.alwaysBounceVertical = false
scrollView.showsVerticalScrollIndicator = false
scrollView.contentInset.bottom = 90
sheetView.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false
gridStack.axis = .vertical
gridStack.alignment = .fill
gridStack.distribution = .fill
gridStack.spacing = 13
contentView.addSubview(gridStack)
gridStack.translatesAutoresizingMaskIntoConstraints = false
for rowIndex in 0..<3 {
let rowStack = UIStackView()
rowStack.axis = .horizontal
rowStack.alignment = .fill
rowStack.distribution = .fillEqually
rowStack.spacing = 13
for columnIndex in 0..<2 {
let itemIndex = rowIndex * 2 + columnIndex
let item = items[itemIndex]
let card = FeatureIntroCardView(item: item)
card.tag = itemIndex
card.addTarget(self, action: #selector(cardTapped(_:)), for: .touchUpInside)
rowStack.addArrangedSubview(card)
card.heightAnchor.constraint(equalTo: card.widthAnchor, multiplier: item.aspectRatio).isActive = true
}
gridStack.addArrangedSubview(rowStack)
}
NSLayoutConstraint.activate([
headerBackgroundView.topAnchor.constraint(equalTo: topAnchor),
headerBackgroundView.leadingAnchor.constraint(equalTo: leadingAnchor),
headerBackgroundView.trailingAnchor.constraint(equalTo: trailingAnchor),
headerBackgroundView.heightAnchor.constraint(equalTo: widthAnchor, multiplier: 230 / 375),
titleLineView.widthAnchor.constraint(equalToConstant: 24),
titleLineView.heightAnchor.constraint(equalToConstant: 3),
titleContainer.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 75),
titleContainer.topAnchor.constraint(equalTo: topAnchor, constant: 91),
sheetView.topAnchor.constraint(equalTo: topAnchor, constant: 200),
sheetView.leadingAnchor.constraint(equalTo: leadingAnchor),
sheetView.trailingAnchor.constraint(equalTo: trailingAnchor),
sheetView.bottomAnchor.constraint(equalTo: bottomAnchor),
scrollView.topAnchor.constraint(equalTo: sheetView.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: sheetView.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: sheetView.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: sheetView.bottomAnchor),
contentView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
contentView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor),
gridStack.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 19),
gridStack.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 15),
gridStack.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -15),
gridStack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -20)
])
}
@objc private func cardTapped(_ sender: FeatureIntroCardView) {
guard items.indices.contains(sender.tag) else { return }
onTapItem?(items[sender.tag].action)
}
}
final class FeatureIntroCardView: UIControl {
private let imageView = UIImageView()
init(item: FeatureIntroItem) {
super.init(frame: .zero)
isAccessibilityElement = true
accessibilityLabel = item.accessibilityTitle
accessibilityTraits = .button
imageView.image = UIImage(named: item.imageName)
imageView.contentMode = .scaleAspectFit
imageView.isUserInteractionEnabled = false
addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: topAnchor),
imageView.leadingAnchor.constraint(equalTo: leadingAnchor),
imageView.trailingAnchor.constraint(equalTo: trailingAnchor),
imageView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var isHighlighted: Bool {
didSet {
imageView.alpha = isHighlighted ? 0.78 : 1
}
}
}