jsdw_ios/QuickLocation/Section/Home/Bubble/CreateBubbleSetupView.swift

290 lines
10 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// CreateBubbleSetupView.swift
// QuickLocation
//
import UIKit
import RxSwift
import RxCocoa
import SwiftDate
/// picker + sheet
final class CreateBubbleSetupView: UIView {
var disposeBag = DisposeBag()
let selectedHour = BehaviorRelay<Int>(value: 1)
var messageText: String = ""
var onConfirmCreate: (() -> Void)?
var onSheetVisibilityChanged: ((Bool) -> Void)?
private let hours = Array(1...6)
let heroView = BubbleHeroView()
let confirmBtn = UIButton(type: .custom)
let sheetConfirmBtn = UIButton(type: .custom)
private let subtitleLab = UILabel()
private let titleLab = UILabel()
private let pickerView = UIPickerView()
private let hourLab = UILabel()
private let sheetOverlay = UIView()
private let sheetPanel = UIView()
private let pinIcon = UIImageView()
private let sheetTitleLab = UILabel()
private let messageView = UIView()
private let messageLab = UILabel()
private let previewAvatar = UIImageView()
private let tipStack = UIStackView()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .white
setupUI()
setupPicker()
setupSheet()
pickerView.selectRow(0, inComponent: 0, animated: false)
selectedHour.accept(hours[0])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
func showNotifySheet(message: String) {
messageText = message
messageLab.text = message
sheetOverlay.isHidden = false
sheetOverlay.alpha = 0
sheetPanel.transform = CGAffineTransform(translationX: 0, y: 40)
onSheetVisibilityChanged?(true)
UIView.animate(withDuration: 0.28, delay: 0, options: .curveEaseOut) {
self.sheetOverlay.alpha = 1
self.sheetPanel.transform = .identity
}
}
func dismissNotifySheet() {
onSheetVisibilityChanged?(false)
UIView.animate(withDuration: 0.22, delay: 0, options: .curveEaseIn) {
self.sheetOverlay.alpha = 0
self.sheetPanel.transform = CGAffineTransform(translationX: 0, y: 40)
} completion: { _ in
self.sheetOverlay.isHidden = true
}
}
var isSheetVisible: Bool { !sheetOverlay.isHidden && sheetOverlay.alpha > 0.01 }
private func setupUI() {
addSubview(heroView)
addSubview(titleLab)
addSubview(subtitleLab)
addSubview(pickerView)
addSubview(hourLab)
addSubview(confirmBtn)
heroView.layoutChain
.top(33)
.leading(30)
.trailing(30)
.heightToWidth(1)
titleLab.text = "您会在气泡待多久?"
titleLab.font = FontManager.boboBold(30)
titleLab.textColor = UIColor(hexStr: "#293445")
titleLab.textAlignment = .center
titleLab.layoutChain.topToBottomOfView(heroView, offset: 25).centerX()
subtitleLab.text = "设置气泡时间"
subtitleLab.font = .systemFont(ofSize: 18, weight: .bold)
subtitleLab.textColor = UIColor(hexStr: "#9CA3AF")
subtitleLab.layoutChain.topToBottomOfView(titleLab, offset: 4).centerX()
pickerView.layoutChain
.topToBottomOfView(subtitleLab, offset: 12)
.edgesHorzontal(15)
.height(180)
hourLab.text = "小时"
hourLab.font = .systemFont(ofSize: 16, weight: .medium)
hourLab.textColor = UIColor(hexStr: "#16B3FF")
hourLab.layoutChain.centerX(self, offset: 100).centerY(pickerView)
confirmBtn.setTitle("确定", for: .normal)
confirmBtn.setTitleColor(.white, for: .normal)
confirmBtn.titleLabel?.font = FontManager.boboBold(18)
confirmBtn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
confirmBtn.cornerRadius = 20
confirmBtn.layoutChain.left(30).right(30).bottom(34).height(56)
}
private func setupPicker() {
pickerView.delegate = self
pickerView.dataSource = self
pickerView.backgroundColor = .clear
}
override func layoutSubviews() {
super.layoutSubviews()
clearPickerSelectionBackground()
}
private func clearPickerSelectionBackground() {
pickerView.subviews.forEach { sub in
sub.backgroundColor = .clear
if sub.frame.height <= 1 {
sub.isHidden = true
}
}
}
private func setupSheet() {
sheetOverlay.backgroundColor = UIColor.black.withAlphaComponent(0.45)
sheetOverlay.isHidden = true
addSubview(sheetOverlay)
sheetOverlay.layoutChain.edges()
sheetPanel.backgroundColor = .white
sheetPanel.layer.cornerRadius = 24
sheetPanel.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
sheetOverlay.addSubview(sheetPanel)
sheetPanel.layoutChain.edgesHorzontal().bottom()
pinIcon.image = UIImage(named: "Bubble/pin")
pinIcon.contentMode = .scaleAspectFit
sheetPanel.addSubview(pinIcon)
pinIcon.layoutChain.top(-22).centerX().width(44).height(44)
sheetTitleLab.text = "通知您的圈子"
sheetTitleLab.font = .systemFont(ofSize: 18, weight: .bold)
sheetTitleLab.textColor = UIColor(hexStr: "#293445")
sheetTitleLab.textAlignment = .center
sheetPanel.addSubview(sheetTitleLab)
sheetTitleLab.layoutChain.top(28).centerX()
messageView.backgroundColor = UIColor(hexStr: "#EBF6F9")
messageView.layer.cornerRadius = 12
sheetPanel.addSubview(messageView)
messageView.addSubview(messageLab)
messageLab.font = .systemFont(ofSize: 15, weight: .medium)
messageLab.textColor = UIColor(hexStr: "#293445")
messageLab.numberOfLines = 0
messageLab.layoutChain.edgesHorzontal(16).edgesVertical(14)
previewAvatar.contentMode = .scaleAspectFill
previewAvatar.clipsToBounds = true
previewAvatar.layer.cornerRadius = 18
previewAvatar.layer.borderWidth = 2
previewAvatar.layer.borderColor = UIColor.white.cgColor
let avatar = AppContextManager.shared.avaterIcon
previewAvatar.image = avatar.size.width > 0 ? avatar : UIImage(named: "Common/default_avatar")
sheetPanel.addSubview(previewAvatar)
messageView.layoutChain
.topToBottomOfView(sheetTitleLab, offset: 20)
.left(24)
.right(72)
previewAvatar.layoutChain
.right(24)
.bottomToView(messageView)
.width(40)
.height(40)
tipStack.axis = .vertical
tipStack.spacing = 12
sheetPanel.addSubview(tipStack)
tipStack.layoutChain
.topToBottomOfView(messageView, offset: 16)
.edgesHorzontal(24)
[
"您的圈子成员只会看到您在气泡中。",
"当您在气泡中,将不会共享您的确切位置。"
].forEach { tipStack.addArrangedSubview(makeTipRow($0)) }
sheetConfirmBtn.setTitle("确定", for: .normal)
sheetConfirmBtn.setTitleColor(.white, for: .normal)
sheetConfirmBtn.titleLabel?.font = FontManager.boboBold(18)
sheetConfirmBtn.backgroundColor = UIColor(hexStr: "#16B3FF")
sheetConfirmBtn.layer.cornerRadius = 16
sheetPanel.addSubview(sheetConfirmBtn)
sheetConfirmBtn.layoutChain
.topToBottomOfView(tipStack, offset: 20)
.edgesHorzontal(20)
.height(56)
.bottom(24 + kSafeBottomMargin)
let tap = UITapGestureRecognizer(target: self, action: #selector(tapMask))
sheetOverlay.addGestureRecognizer(tap)
}
private func makeTipRow(_ text: String) -> UIView {
let row = UIView()
let star = UIImageView(image: UIImage(systemName: "sparkle"))
star.tintColor = UIColor(hexStr: "#16B3FF")
star.contentMode = .scaleAspectFit
let lab = UILabel()
lab.text = text
lab.font = .systemFont(ofSize: 14, weight: .medium)
lab.textColor = UIColor(hexStr: "#767676")
lab.numberOfLines = 0
row.addSubview(star)
row.addSubview(lab)
star.layoutChain.left().top(2).width(14).height(14)
lab.layoutChain.leftToRightOfView(star, offset: 8).right().top().bottom()
return row
}
@objc private func tapMask(_ gesture: UITapGestureRecognizer) {
let point = gesture.location(in: sheetPanel)
if sheetPanel.bounds.contains(point) { return }
dismissNotifySheet()
}
func buildMessage(for hours: Int) -> String {
let endDate = Calendar.current.date(byAdding: .hour, value: hours, to: Date()) ?? Date()
let timeStr = endDate.toFormat("HH:mm")
return "\(timeStr)之前,我会一直在这个区域。如果需要我帮忙,请给我发消息。"
}
}
extension CreateBubbleSetupView: UIPickerViewDataSource, UIPickerViewDelegate {
func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 }
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
hours.count
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { 44 }
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let container = view as? UIView ?? UIView()
container.subviews.forEach { $0.removeFromSuperview() }
let label = UILabel()
label.textAlignment = .center
label.font = .systemFont(ofSize: 20, weight: .medium)
let selected = row == pickerView.selectedRow(inComponent: component)
label.textColor = selected ? UIColor(hexStr: "#16B3FF") : UIColor(hexStr: "#999999")
label.text = "\(hours[row])"
container.addSubview(label)
label.layoutChain.center().width(60).height(36)
if selected {
let capsule = UIView()
capsule.backgroundColor = UIColor(hexStr: "#E3F6FF")
capsule.layer.cornerRadius = 14
container.insertSubview(capsule, at: 0)
capsule.layoutChain.center().width(130).height(36)
}
return container
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedHour.accept(hours[row])
pickerView.reloadAllComponents()
clearPickerSelectionBackground()
}
}