241 lines
7.7 KiB
Swift
241 lines
7.7 KiB
Swift
//
|
||
// GroupChooseView.swift
|
||
// QuickLocation
|
||
//
|
||
// Created by 八条 on 2026/6/27.
|
||
//
|
||
|
||
import UIKit
|
||
import ObjectMapper
|
||
|
||
class GroupChooseView: UIView {
|
||
|
||
private static let shared = GroupChooseView(frame: CGRect(origin: .zero, size: kScreenSize))
|
||
|
||
private var groupModel: GroupModel? {
|
||
didSet {
|
||
guard let model = groupModel else { return }
|
||
groupList = model.groups
|
||
let count = min(model.groups.count, 5)
|
||
tableView.isScrollEnabled = model.groups.count > 5
|
||
tableView.layoutChain.height(CGFloat(count * 68), relation: .greaterThanOrEqual)
|
||
}
|
||
}
|
||
|
||
private var groupInfo: [String: Any] {
|
||
guard let model = groupModel,
|
||
let groupInfoModel = model.groups.first(where: { $0.group_key == defaultGroupKey }) else { return [:] }
|
||
return groupInfoModel.toJSON()
|
||
}
|
||
|
||
private var defaultGroupKey: String = "" {
|
||
didSet { tableView.reloadData() }
|
||
}
|
||
|
||
private var groupList: [GroupInfoModel] = [] {
|
||
didSet { tableView.reloadData() }
|
||
}
|
||
|
||
private var completion: ((String?) -> Void)?
|
||
|
||
@objc func tap() { completion?(nil) }
|
||
|
||
@objc func cancelAction(button: UIButton) { completion?(nil) }
|
||
|
||
@objc func inviteAction(button: UIButton) {
|
||
completion?(nil)
|
||
AppRouter.push(Route.inviteJoin, userInfo: ["groupInfo": self.groupInfo])
|
||
}
|
||
|
||
private lazy var bgView: UIView = {
|
||
let view = UIView()
|
||
view.backgroundColor = .black.withAlphaComponent(0.5)
|
||
view.clipsToBounds = true
|
||
return view
|
||
}()
|
||
|
||
lazy var infoView: UIView = {
|
||
let view = UIView()
|
||
view.backgroundColor = .white
|
||
view.layer.cornerRadius = 10
|
||
view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||
return view
|
||
}()
|
||
|
||
lazy var titleLab: UILabel = {
|
||
let label = UILabel()
|
||
label.text = "选择圈子"
|
||
label.font = .systemFont(ofSize: 16, weight: .bold)
|
||
label.textColor = ThemeManager.shared.color.titleAuxColor
|
||
return label
|
||
}()
|
||
|
||
lazy var tableView: UITableView = {
|
||
let tableView = UITableView(frame: .zero, style: .grouped)
|
||
tableView.backgroundColor = .white
|
||
tableView.separatorStyle = .none
|
||
tableView.estimatedRowHeight = 68
|
||
tableView.showsVerticalScrollIndicator = false
|
||
tableView.bounces = false
|
||
tableView.isScrollEnabled = false
|
||
tableView.register(GroupListCell.self)
|
||
tableView.tableHeaderView = UIView(frame: CGRectMake(0, 0, kScreenWidth, 10))
|
||
tableView.dataSource = self
|
||
tableView.delegate = self
|
||
return tableView
|
||
}()
|
||
|
||
lazy var cancelBtn: UIButton = {
|
||
let btn = UIButton(type: .custom)
|
||
btn.setTitle("取消", for: .normal)
|
||
btn.setTitleColor(UIColor(hexStr: "#16B3FF"), for: .normal)
|
||
btn.titleLabel?.font = .systemFont(ofSize: 15, weight: .medium)
|
||
btn.backgroundColor = .white
|
||
btn.borderWidth = 1
|
||
btn.borderColor = UIColor(hexStr: "#16B3FF")
|
||
btn.cornerRadius = 20
|
||
btn.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
|
||
return btn
|
||
}()
|
||
|
||
lazy var inviteBtn: UIButton = {
|
||
let btn = UIButton(type: .custom)
|
||
btn.setTitle("邀请", for: .normal)
|
||
btn.setTitleColor(.white, for: .normal)
|
||
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
||
btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
|
||
btn.cornerRadius = 20
|
||
btn.addTarget(self, action: #selector(inviteAction), for: .touchUpInside)
|
||
return btn
|
||
}()
|
||
|
||
override init(frame: CGRect) {
|
||
super.init(frame: frame)
|
||
backgroundColor = .clear
|
||
addSubview(bgView)
|
||
bgView.addSubview(infoView)
|
||
infoView.addSubview(titleLab)
|
||
infoView.addSubview(tableView)
|
||
infoView.addSubview(cancelBtn)
|
||
infoView.addSubview(inviteBtn)
|
||
|
||
// bgView 全屏
|
||
bgView.layoutChain.edges()
|
||
|
||
// infoView 横向撑满,底部对齐,高度由内容决定
|
||
infoView.layoutChain
|
||
.edgesHorzontal()
|
||
.bottom()
|
||
|
||
titleLab.layoutChain
|
||
.top(16)
|
||
.left(12)
|
||
|
||
cancelBtn.layoutChain
|
||
.left(15)
|
||
.bottom(20 + kSafeBottomMargin)
|
||
.widthToView(inviteBtn)
|
||
.height(44)
|
||
|
||
inviteBtn.layoutChain
|
||
.leftToRightOfView(cancelBtn, offset: 7)
|
||
.right(15)
|
||
.bottomToView(cancelBtn)
|
||
.height(44)
|
||
.widthToView(inviteBtn)
|
||
|
||
tableView.layoutChain
|
||
.topToBottomOfView(titleLab, offset: 10)
|
||
.edgesHorzontal()
|
||
.bottomToTopOfView(cancelBtn, offset: -17)
|
||
.height(78, relation: .greaterThanOrEqual)
|
||
|
||
let tap = UITapGestureRecognizer(target: self, action: #selector(tap))
|
||
tap.delegate = self
|
||
addGestureRecognizer(tap)
|
||
}
|
||
|
||
required init?(coder aDecoder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
override func layoutSubviews() {
|
||
super.layoutSubviews()
|
||
}
|
||
}
|
||
|
||
// MARK: - Public
|
||
extension GroupChooseView {
|
||
|
||
/// 显示选择弹窗(底部弹出)
|
||
static func show(groupModel: GroupModel,
|
||
completion: @escaping ((String?) -> Void)) {
|
||
guard let superView = kKeyWindow else { return }
|
||
|
||
let shared = GroupChooseView.shared
|
||
if shared.superview != nil {
|
||
shared.removeFromSuperview()
|
||
}
|
||
|
||
shared.groupModel = groupModel
|
||
shared.frame = CGRect(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight)
|
||
superView.addSubview(shared)
|
||
superView.bringSubviewToFront(shared)
|
||
|
||
shared.bgView.alpha = 0
|
||
shared.infoView.transform = CGAffineTransform(translationX: 0, y: shared.infoView.frame.maxY + 100)
|
||
|
||
shared.completion = { text in
|
||
completion(text)
|
||
GroupChooseView.dismiss()
|
||
}
|
||
|
||
shared.layoutIfNeeded()
|
||
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut) {
|
||
shared.bgView.alpha = 1
|
||
shared.infoView.transform = .identity
|
||
}
|
||
}
|
||
|
||
/// 关闭(底部滑出)
|
||
static func dismiss() {
|
||
guard GroupChooseView.shared.superview != nil else { return }
|
||
let shared = GroupChooseView.shared
|
||
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseIn) {
|
||
shared.bgView.alpha = 0
|
||
shared.infoView.transform = CGAffineTransform(translationX: 0, y: shared.infoView.frame.maxY + 100)
|
||
} completion: { _ in
|
||
shared.removeFromSuperview()
|
||
shared.infoView.transform = .identity
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - UIGestureRecognizerDelegate
|
||
extension GroupChooseView: UIGestureRecognizerDelegate {
|
||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
|
||
if let view = touch.view, !(view == self || view == bgView) {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
}
|
||
|
||
// MARK: - UITableViewDataSource & UITableViewDelegate
|
||
extension GroupChooseView: UITableViewDataSource, UITableViewDelegate {
|
||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||
groupList.count
|
||
}
|
||
|
||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||
let cell: GroupListCell = tableView.dequeueReusableCell(for: indexPath)
|
||
cell.configure(model: groupList[indexPath.row],
|
||
isSelected: defaultGroupKey == groupList[indexPath.row].group_key)
|
||
return cell
|
||
}
|
||
|
||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||
defaultGroupKey = groupList[indexPath.row].group_key
|
||
}
|
||
}
|