// // MOGiftBottomMenuView.swift // MiMoLive // // Created by OneeChan on 2025/9/5. // import Foundation import UIKit import SnapKit @objc protocol MOGiftBottomMenuViewDelegate { // Recharge func giftBottomMenuViewClickRecharge(view: MOGiftBottomMenuView) // Gift func giftBottomMenuViewDidSelectNum(view: MOGiftBottomMenuView, num: Int, isCustom: Bool) func giftBottomMenuViewClickSendGift(view: MOGiftBottomMenuView) func giftBottomMenuViewClickCustom(view: MOGiftBottomMenuView) // Bag func giftBottomMenuViewClickSendBag(view: MOGiftBottomMenuView) // Props func giftBottomMenuViewClickUse(view: MOGiftBottomMenuView) } @objcMembers class MOGiftBottomMenuView: UIView { weak var delegate: MOGiftBottomMenuViewDelegate? @objc enum GiftBottomMenuType: Int { case none case gift case bag case props } private var curType: GiftBottomMenuType = .gift private var giftView: UIView? private var diamondLabel: UILabel? private var sendGiftView: MOSendGiftView? private var bagView: UIView? private var propView: UIView? private var usePropButon: MOGiftGradientButton? override init(frame: CGRect) { super.init(frame: frame) setupViews() updateViewType(curType) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func updateSelectItem(_ item: Any?) { guard let item else { updateViewType(.none) return } if let item = item as? MOGiftlist { if item.isBag { updateViewType(.bag) } else { enableGiftSendView(true) updateViewType(.gift) } } else if let item = item as? MOShopList { updateViewType(.props) if item.used { usePropButon?.title = NSLocalizedString("mimo_2_gift_list_prpps_a_use", comment: "") } else { usePropButon?.title = NSLocalizedString("mimo_2_gift_list_prpps_use", comment: "") } } else { updateViewType(.none) } } func updateViewType(_ type: GiftBottomMenuType) { curType = type let showView: UIView? = switch type { case .none: nil case .gift: self.giftView case .bag: self.bagView case .props: self.propView } let showings = [self.giftView, self.bagView, self.propView] .filter { $0?.isHidden == false && $0 != showView } showings.forEach { $0?.isHidden = true } // 已经在展示,不需要调整 if showView?.isHidden == false { return } showView?.isHidden = false } func updateUserDiamond(_ count: Double) { var zuanNumStr = "" if count < 10_000_000 { // 1千万以下 zuanNumStr = String(format: "%.f", count) } else if count < 1_000_000_000 { // 1千万到10亿 let firstTwoDigits = Int(count / 10_000) zuanNumStr = String( format: "%ld.%02ldM", firstTwoDigits / 100, firstTwoDigits % 100 ) } else { // 10亿以上 let firstTwoDigits = Int(count / 10_000_000) zuanNumStr = String( format: "%ld.%02ldB", firstTwoDigits / 100, firstTwoDigits % 100 ) } diamondLabel?.text = "\(zuanNumStr)" } func selectGiftNum(_ num: Int) { sendGiftView?.updateGiftNum(num) } func curGiftNum() -> Int { sendGiftView?.curGiftNum() ?? 1 } func enableGiftSendView(_ enable: Bool) { sendGiftView?.isHidden = !enable } func enableGiftNum(_ enable: Bool) { sendGiftView?.enableGiftNum(enable) } func updateCustomNum(_ num: Int) { sendGiftView?.updateCustomNum(num) } } // MARK: Private extension MOGiftBottomMenuView { } // MARK: UI 事件 extension MOGiftBottomMenuView { @objc func handleRechargeButtonClick() { delegate?.giftBottomMenuViewClickRecharge(view: self) } @objc func handleSendBagButtonClick() { delegate?.giftBottomMenuViewClickSendBag(view: self) } @objc func handleUsePropsButtonClick() { delegate?.giftBottomMenuViewClickUse(view: self) } } // MARK: MOSendGiftDelegate extension MOGiftBottomMenuView: MOSendGiftViewDelegate { func sendGiftViewDidSelectNum( view: MOSendGiftView, num: Int, isCustom: Bool ) { delegate? .giftBottomMenuViewDidSelectNum( view: self, num: num, isCustom: isCustom ) } func sendGiftViewClickSend(view: MOSendGiftView) { delegate?.giftBottomMenuViewClickSendGift(view: self) } func sendGiftViewClickCustom(view: MOSendGiftView) { delegate?.giftBottomMenuViewClickCustom(view: self) } } // MARK: UI 视图构建 extension MOGiftBottomMenuView { // UI 组装 private func setupViews() { let giftView = buildGiftMenuView() giftView.isHidden = true addSubview(giftView) giftView.snp.makeConstraints { make in make.leading.trailing.bottom.equalToSuperview() make.top.bottom.equalToSuperview() } self.giftView = giftView let bagView = buildBagMenuView() bagView.isHidden = true addSubview(bagView) bagView.snp.makeConstraints { make in make.edges.equalToSuperview() } self.bagView = bagView let propsView = buildPropsMenuView() propsView.isHidden = true addSubview(propsView) propsView.snp.makeConstraints { make in make.edges.equalToSuperview() } self.propView = propsView } // Gift Menu private func buildGiftMenuView() -> UIView { let container = UIView() let diamondView = buildDiamondView() container.addSubview(diamondView) diamondView.snp.makeConstraints { make in make.top.bottom.equalToSuperview() make.leading.equalToSuperview().offset(12) } let sendView = MOSendGiftView() sendView.delegate = self container.addSubview(sendView) sendView.snp.makeConstraints { make in make.top.bottom.equalToSuperview() make.trailing.equalToSuperview().offset(-12) make.leading.equalTo(diamondView.snp.trailing).offset(8) } self.sendGiftView = sendView return container } // 钻石界面 private func buildDiamondView() -> UIView { let container = UIView() container.layer.cornerRadius = 10 container.backgroundColor = .white.withAlphaComponent(0.15) let diamond = UIImageView() diamond.image = UIImage(named: "icon_gift_zuan") container.addSubview(diamond) diamond.snp.makeConstraints { make in make.top.equalToSuperview().offset(7) make.bottom.equalToSuperview().offset(-7) make.leading.equalToSuperview().offset(10) make.width.height.equalTo(14) } let label = UILabel() label.textColor = .white label.font = MOTextTools.mediumFont(12.0) container.addSubview(label) label.snp.makeConstraints { make in make.centerY.equalToSuperview() make.leading.equalTo(diamond.snp.trailing).offset(3) } self.diamondLabel = label let arrow = UIImageView() arrow.image = UIImage(named: "icon_arrow_right_gray") container.addSubview(arrow) arrow.snp.makeConstraints { make in make.centerY.equalToSuperview() make.leading.equalTo(label.snp.trailing).offset(5) make.trailing.equalToSuperview().offset(-10) } let button = UIButton() button .addTarget( self, action: #selector(handleRechargeButtonClick), for: .touchUpInside ) container.addSubview(button) button.snp.makeConstraints { make in make.edges.equalToSuperview() } return container } // Bag View private func buildBagMenuView() -> UIView { let container = UIView() let send = MOGiftGradientButton() send .addTarget( self, action: #selector(handleSendBagButtonClick), for: .touchUpInside ) send.title = "Send" container.addSubview(send) send.snp.makeConstraints { make in make.top.bottom.equalToSuperview() make.trailing.equalToSuperview().offset(-12) } return container } // Props View private func buildPropsMenuView() -> UIView { let container = UIView() let use = MOGiftGradientButton() use.addTarget( self, action: #selector(handleUsePropsButtonClick), for: .touchUpInside ) use.title = "Use" container.addSubview(use) use.snp.makeConstraints { make in make.top.bottom.equalToSuperview() make.trailing.equalToSuperview().offset(-12) } self.usePropButon = use return container } } private class MOGiftGradientButton: UIButton { var title = "" { didSet { textLabel.text = title } } private let gradientLayer = CAGradientLayer() private let textLabel = UILabel() override init(frame: CGRect) { super.init(frame: frame) setupViews() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() CATransaction.begin() CATransaction.setDisableActions(true) layer.sublayers?.forEach({ layer in if layer is CAGradientLayer { layer.frame = bounds } }) CATransaction.commit() } private func setupViews() { let graLayer = CAGradientLayer() graLayer.startPoint = CGPoint(x: 0, y: 0.5) graLayer.endPoint = CGPoint(x: 1, y: 0.5) graLayer.colors = [ UIColor( red: 255/255.0, green: 77/255.0, blue: 166/255.0, alpha: 1 ).cgColor, UIColor( red: 67/255.0, green: 99/255.0, blue: 255/255.0, alpha: 1 ).cgColor ]; graLayer.locations = [0, 1.0] layer.insertSublayer(graLayer, at: 0) layer.cornerRadius = 10 layer.masksToBounds = true textLabel.text = "Use" textLabel.font = MOTextTools.mediumFont(12.0) textLabel.textColor = .white addSubview(textLabel) textLabel.snp.makeConstraints { make in make.edges .equalToSuperview() .inset(UIEdgeInsets(top: 6, left: 16, bottom: 6, right: 16)) } } } //#if DEBUG //import SwiftUI // //struct MOGiftBottomMenuViewPreview: UIViewRepresentable { // func makeUIView(context: Context) -> some UIView { // let container = UIView() // container.backgroundColor = .black // // let view = MOGiftBottomMenuView() // container.addSubview(view) // view.snp.makeConstraints { make in // make.centerY.equalToSuperview() // make.leading.trailing.equalToSuperview() // } // // return container // } // // func updateUIView(_ uiView: UIViewType, context: Context) { // // } //} // //#Preview(body: { // VStack { // MOGiftBottomMenuViewPreview() // } //}) // //#endif