// // FriendsPiecesViews.swift // Crush // // Created by Leon on 2025/8/14. // import UIKit /// 当前 heartbeat 排名 class FriendsHeartBeatHead: UIView { var stackV: UIStackView! // Part 1 var blockView: UIView! var queryButton: EPIconGhostButton! var label: LineSpaceLabel! // Part 2 var noticeOnceView: FriendsNoticeOnceView! var heightChangeBlock: ((CGFloat) -> Void)? override init(frame: CGRect) { super.init(frame: frame) setupViews() setupData() setupEvent() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupViews() { stackV = { let v = UIStackView() v.axis = .vertical addSubview(v) v.snp.makeConstraints { make in make.top.equalTo(16) make.leading.equalToSuperview().offset(8) make.trailing.equalToSuperview().offset(-8) } return v }() blockView = { let v = UIView() v.layer.cornerRadius = 8 v.layer.masksToBounds = true v.backgroundColor = .c.csbn // addSubview(v) // v.snp.makeConstraints { make in // make.top.equalToSuperview().offset(8) // make.leading.equalToSuperview().offset(8) // make.trailing.equalToSuperview().offset(-8) // } stackV.addArrangedSubview(v) return v }() queryButton = { let v = EPIconGhostButton(radius: .none, iconSize: .small, iconCode: .faq) v.addTarget(self, action: #selector(tapQueryButton), for: .touchUpInside) blockView.addSubview(v) v.snp.makeConstraints { make in make.centerY.equalToSuperview() make.size.equalTo(v.bgImageSize()) make.trailing.equalToSuperview().offset(-16) } return v }() label = { let v = LineSpaceLabel() let typo = CLSystemToken.typography(token: .tls) v.config(typo) v.textColor = .text blockView.addSubview(v) v.snp.makeConstraints { make in make.leading.equalToSuperview().offset(16) make.top.equalToSuperview().offset(8) make.bottom.equalToSuperview().offset(-8) make.trailing.equalTo(queryButton.snp.leading).offset(8) } return v }() noticeOnceView = { let v = FriendsNoticeOnceView() stackV.addArrangedSubview(v) return v }() noticeOnceView.isHidden = true blockView.isHidden = true } private func setupData() { //#warning("test") // testData() } private func testData(){ label.text = "Sum of heartbeat values: top 10.12%" } private func setupEvent() { noticeOnceView.tapCloseAction = {[weak self] in self?.blockView.isHidden = false } } // MARK: - Public public func showNoticeOnce(_ show: Bool){ noticeOnceView.isHidden = !show blockView.isHidden = show } /// 0.9 -> 90% public func config(percent:CGFloat?){ if self.noticeOnceView.isHidden == true{ self.blockView.isHidden = false } let percentValue = percent ?? 0.0 // 限制范围 0 ~ 1,避免传入非法值 let clamped = min(max(percentValue, 0.0), 1.0) // 转换成百分比,保留两位小数(如果是整数则自动不显示多余小数) let formatter = NumberFormatter() formatter.numberStyle = .percent formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 2 let formatPercent = formatter.string(from: NSNumber(value: Double(clamped))) ?? "0%" // 更新 UI label.text = "Sum of heartbeat values: top \(formatPercent)" } // MARK: - Action @objc private func tapQueryButton() { let alert = Alert(title: "Tips", text: "与你的心动值达到15.0摄氏度以上的角色作为最为排名对象,按照这些角色心动值总和进行排名") let action1 = AlertAction(title: "Got it", actionStyle: .confirm) { } alert.addAction(action1) alert.show() } override func layoutSubviews() { super.layoutSubviews() let maxY = stackV.frame.maxY + 8 heightChangeBlock?(maxY) } }