// // EPPolicyLabel.swift // YuMi // // Created by AI on 2025-01-27. // import UIKit class EPPolicyLabel: UILabel { // MARK: - Properties var onUserAgreementTapped: (() -> Void)? var onPrivacyPolicyTapped: (() -> Void)? // MARK: - Initialization override init(frame: CGRect) { super.init(frame: frame) setup() } required init?(coder: NSCoder) { super.init(coder: coder) setup() } // MARK: - Setup private func setup() { numberOfLines = 0 isUserInteractionEnabled = true // 使用 YMLocalizedString 获取文案 let fullText = YMLocalizedString("XPLoginViewController6") let userAgreementText = YMLocalizedString("XPLoginViewController7") let privacyPolicyText = YMLocalizedString("XPLoginViewController9") let attributedString = NSMutableAttributedString(string: fullText) attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.darkGray, range: NSRange(location: 0, length: fullText.count)) attributedString.addAttribute(NSAttributedString.Key.font, value: UIFont.systemFont(ofSize: 12), range: NSRange(location: 0, length: fullText.count)) // 高亮用户协议(蓝色) if let userRange = fullText.range(of: userAgreementText) { let nsRange = NSRange(userRange, in: fullText) attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.systemBlue, range: nsRange) attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: nsRange) } // 高亮隐私政策(蓝色) if let privacyRange = fullText.range(of: privacyPolicyText) { let nsRange = NSRange(privacyRange, in: fullText) attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.systemBlue, range: nsRange) attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: nsRange) } attributedText = attributedString // 添加点击手势 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))) addGestureRecognizer(tapGesture) } // MARK: - Actions @objc private func handleTap(_ gesture: UITapGestureRecognizer) { guard let attributedText = self.attributedText else { print("[EPPolicyLabel] No attributed text") return } let text = attributedText.string let userAgreementText = YMLocalizedString("XPLoginViewController7") let privacyPolicyText = YMLocalizedString("XPLoginViewController9") print("[EPPolicyLabel] Tap detected, text: \(text)") let layoutManager = NSLayoutManager() let textContainer = NSTextContainer(size: bounds.size) let textStorage = NSTextStorage(attributedString: attributedText) layoutManager.addTextContainer(textContainer) textStorage.addLayoutManager(layoutManager) textContainer.lineFragmentPadding = 0 textContainer.maximumNumberOfLines = numberOfLines textContainer.lineBreakMode = lineBreakMode let locationOfTouchInLabel = gesture.location(in: self) let textBoundingBox = layoutManager.usedRect(for: textContainer) // 根据 textAlignment 计算偏移 var textContainerOffset = CGPoint.zero switch textAlignment { case .left, .natural, .justified: textContainerOffset = CGPoint(x: 0, y: (bounds.height - textBoundingBox.height) / 2) case .center: textContainerOffset = CGPoint(x: (bounds.width - textBoundingBox.width) / 2, y: (bounds.height - textBoundingBox.height) / 2) case .right: textContainerOffset = CGPoint(x: bounds.width - textBoundingBox.width, y: (bounds.height - textBoundingBox.height) / 2) @unknown default: textContainerOffset = CGPoint(x: 0, y: (bounds.height - textBoundingBox.height) / 2) } let locationOfTouchInTextContainer = CGPoint(x: locationOfTouchInLabel.x - textContainerOffset.x, y: locationOfTouchInLabel.y - textContainerOffset.y) // 确保点击在文本区域内 guard textBoundingBox.contains(locationOfTouchInTextContainer) else { print("[EPPolicyLabel] Tap outside text bounds") return } let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil) print("[EPPolicyLabel] Character index: \(indexOfCharacter)") // 检查点击位置 if let userRange = text.range(of: userAgreementText) { let nsRange = NSRange(userRange, in: text) print("[EPPolicyLabel] User agreement range: \(nsRange)") if NSLocationInRange(indexOfCharacter, nsRange) { print("[EPPolicyLabel] User agreement tapped!") onUserAgreementTapped?() return } } if let privacyRange = text.range(of: privacyPolicyText) { let nsRange = NSRange(privacyRange, in: text) print("[EPPolicyLabel] Privacy policy range: \(nsRange)") if NSLocationInRange(indexOfCharacter, nsRange) { print("[EPPolicyLabel] Privacy policy tapped!") onPrivacyPolicyTapped?() return } } print("[EPPolicyLabel] No link tapped") } }