import SwiftUI // MARK: - User Agreement View Component struct UserAgreementView: View { @Binding var isAgreed: Bool let onUserServiceTapped: () -> Void let onPrivacyPolicyTapped: () -> Void var body: some View { HStack(alignment: .center, spacing: 12) { // 左侧勾选按钮 Button(action: { isAgreed.toggle() }) { Image(systemName: isAgreed ? "checkmark.circle.fill" : "circle") .font(.system(size: 22)) .foregroundColor(isAgreed ? Color(hex: 0x8A4FFF) : Color(hex: 0x666666)) } // 右侧富文本 Text(createAttributedText()) .font(.system(size: 14)) .multilineTextAlignment(.leading) .environment(\.openURL, OpenURLAction { url in if url.absoluteString == "user-service-agreement" { onUserServiceTapped() return .handled } else if url.absoluteString == "privacy-policy" { onPrivacyPolicyTapped() return .handled } return .systemAction }) } .frame(maxWidth: .infinity) // 占满可用宽度 .padding(.horizontal, 29) // 与登录按钮保持一致的边距 } // MARK: - Private Methods private func createAttributedText() -> AttributedString { var attributedString = AttributedString("login.agreement_policy".localized) // 设置默认颜色 attributedString.foregroundColor = Color(hex: 0x666666) // 找到并设置 "用户协议" 的样式和链接 if let userServiceRange = attributedString.range(of: "login.agreement".localized) { attributedString[userServiceRange].foregroundColor = Color(hex: 0x8A4FFF) attributedString[userServiceRange].underlineStyle = .single attributedString[userServiceRange].link = URL(string: "user-service-agreement") } // 找到并设置 "隐私政策" 的样式和链接 if let privacyPolicyRange = attributedString.range(of: "login.policy".localized) { attributedString[privacyPolicyRange].foregroundColor = Color(hex: 0x8A4FFF) attributedString[privacyPolicyRange].underlineStyle = .single attributedString[privacyPolicyRange].link = URL(string: "privacy-policy") } return attributedString } } #Preview { VStack(spacing: 20) { UserAgreementView( isAgreed: .constant(true), onUserServiceTapped: { debugInfo("User Service Agreement tapped") }, onPrivacyPolicyTapped: { debugInfo("Privacy Policy tapped") } ) UserAgreementView( isAgreed: .constant(true), onUserServiceTapped: { debugInfo("User Service Agreement tapped") }, onPrivacyPolicyTapped: { debugInfo("Privacy Policy tapped") } ) } .padding() .background(Color.gray.opacity(0.1)) }