// // PigeonUploadPopView.swift // QuickLocation // import UIKit final class PigeonUploadPopView: UIView, UIGestureRecognizerDelegate { private static let shared = PigeonUploadPopView(frame: CGRect(origin: .zero, size: kScreenSize)) private var onAlbum: (() -> Void)? private var onCamera: (() -> Void)? static func show(onAlbum: @escaping () -> Void, onCamera: @escaping () -> Void) { guard let superView = kKeyWindow else { return } let pop = PigeonUploadPopView.shared if pop.superview != nil { pop.removeFromSuperview() } pop.onAlbum = onAlbum pop.onCamera = onCamera pop.frame = superView.bounds pop.dimView.alpha = 0 pop.sheetView.transform = CGAffineTransform(translationX: 0, y: kScreenHeight) superView.addSubview(pop) superView.bringSubviewToFront(pop) pop.layoutIfNeeded() UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut) { pop.dimView.alpha = 1 pop.sheetView.transform = .identity } } static func dismiss(completion: (() -> Void)? = nil) { let pop = PigeonUploadPopView.shared guard pop.superview != nil else { completion?() return } UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseIn]) { pop.dimView.alpha = 0 pop.sheetView.transform = CGAffineTransform(translationX: 0, y: kScreenHeight) } completion: { _ in pop.sheetView.transform = .identity pop.onAlbum = nil pop.onCamera = nil pop.removeFromSuperview() completion?() } } override init(frame: CGRect) { super.init(frame: frame) setupUI() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @objc private func tapMask() { PigeonUploadPopView.dismiss() } @objc private func tapAlbum() { let action = onAlbum PigeonUploadPopView.dismiss { action?() } } @objc private func tapCamera() { let action = onCamera PigeonUploadPopView.dismiss { action?() } } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { let point = touch.location(in: self) return !sheetView.frame.contains(point) } private func setupUI() { addSubview(dimView) addSubview(sheetView) sheetView.addSubview(headerView) sheetView.addSubview(albumButton) sheetView.addSubview(cameraButton) sheetView.addSubview(albumLabel) sheetView.addSubview(cameraLabel) dimView.layoutChain.edges() sheetView.layoutChain .bottom() .edgesHorzontal() headerView.layoutChain .top() .edgesHorzontal() .heightToWidth(200.0 / 750.0) albumButton.layoutChain .topToBottomOfView(headerView, offset: 8) .centerX(sheetView, offset: -80) .width(80) .height(80) cameraButton.layoutChain .topToView(albumButton) .centerX(sheetView, offset: 80) .width(80) .height(80) albumLabel.layoutChain .topToBottomOfView(albumButton, offset: 10) .centerX(albumButton) .bottom(22 + kSafeBottomMargin) cameraLabel.layoutChain .topToView(albumLabel) .centerX(cameraButton) let tap = UITapGestureRecognizer(target: self, action: #selector(tapMask)) tap.delegate = self addGestureRecognizer(tap) } private lazy var dimView: UIView = { let view = UIView() view.backgroundColor = UIColor.black.withAlphaComponent(0.45) return view }() private lazy var sheetView: UIView = { let view = UIView() view.backgroundColor = .white view.layer.cornerRadius = 40 view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] view.clipsToBounds = true return view }() private lazy var headerView: UIImageView = { let view = UIImageView(image: UIImage(named: "PigeonMessage/upload_header")) view.contentMode = .scaleToFill return view }() private lazy var albumButton: UIButton = { makeOptionButton(imageName: "PigeonMessage/gallery", action: #selector(tapAlbum)) }() private lazy var cameraButton: UIButton = { makeOptionButton(imageName: "PigeonMessage/camera", action: #selector(tapCamera)) }() private lazy var albumLabel: UILabel = { makeOptionLabel("本地上传") }() private lazy var cameraLabel: UILabel = { makeOptionLabel("拍照上传") }() private func makeOptionButton(imageName: String, action: Selector) -> UIButton { let button = UIButton(type: .custom) button.backgroundColor = UIColor(hexStr: "#F5F5F5") button.layer.cornerRadius = 20 button.setImage(UIImage(named: imageName), for: .normal) button.addTarget(self, action: action, for: .touchUpInside) return button } private func makeOptionLabel(_ text: String) -> UILabel { let label = UILabel() label.text = text label.font = .systemFont(ofSize: 14, weight: .medium) label.textColor = UIColor(hexStr: "#293445") label.textAlignment = .center return label } }