import SwiftUI // MARK: - 通用输入字段组件 struct InputFieldView: View { let title: String let isRequired: Bool let placeholder: String let text: Binding let keyboardType: UIKeyboardType let autocapitalization: UITextAutocapitalizationType let icon: String? let isSecure: Bool let isFocused: Bool let onFocusChange: (Bool) -> Void init( title: String, isRequired: Bool = false, placeholder: String, text: Binding, keyboardType: UIKeyboardType = .default, autocapitalization: UITextAutocapitalizationType = .sentences, icon: String? = nil, isSecure: Bool = false, isFocused: Bool = false, onFocusChange: @escaping (Bool) -> Void = { _ in } ) { self.title = title self.isRequired = isRequired self.placeholder = placeholder self.text = text self.keyboardType = keyboardType self.autocapitalization = autocapitalization self.icon = icon self.isSecure = isSecure self.isFocused = isFocused self.onFocusChange = onFocusChange } var body: some View { VStack(alignment: .leading, spacing: 8) { InputTitleView.required(title, icon: icon) Group { if isSecure { SecureField(placeholder, text: text) } else { TextField(placeholder, text: text) } } .textFieldStyle(RoundedBorderTextFieldStyle()) .keyboardType(keyboardType) .autocapitalization(autocapitalization) .onTapGesture { onFocusChange(true) } .onChange(of: isFocused) { newValue in onFocusChange(newValue) } } } } // MARK: - 预定义的输入字段样式 extension InputFieldView { static func text( title: String, isRequired: Bool = false, placeholder: String, text: Binding, icon: String? = nil, isFocused: Bool = false, onFocusChange: @escaping (Bool) -> Void = { _ in } ) -> InputFieldView { InputFieldView( title: title, isRequired: isRequired, placeholder: placeholder, text: text, icon: icon, isFocused: isFocused, onFocusChange: onFocusChange ) } static func email( title: String, isRequired: Bool = false, placeholder: String, text: Binding, icon: String? = nil, isFocused: Bool = false, onFocusChange: @escaping (Bool) -> Void = { _ in } ) -> InputFieldView { InputFieldView( title: title, isRequired: isRequired, placeholder: placeholder, text: text, keyboardType: .emailAddress, autocapitalization: .sentences, icon: icon, isFocused: isFocused, onFocusChange: onFocusChange ) } static func phone( title: String, isRequired: Bool = false, placeholder: String, text: Binding, icon: String? = nil, isFocused: Bool = false, onFocusChange: @escaping (Bool) -> Void = { _ in } ) -> InputFieldView { InputFieldView( title: title, isRequired: isRequired, placeholder: placeholder, text: text, keyboardType: .phonePad, icon: icon, isFocused: isFocused, onFocusChange: onFocusChange ) } static func url( title: String, isRequired: Bool = false, placeholder: String, text: Binding, icon: String? = nil, isFocused: Bool = false, onFocusChange: @escaping (Bool) -> Void = { _ in } ) -> InputFieldView { InputFieldView( title: title, isRequired: isRequired, placeholder: placeholder, text: text, keyboardType: .URL, autocapitalization: .sentences, icon: icon, isFocused: isFocused, onFocusChange: onFocusChange ) } static func password( title: String, isRequired: Bool = false, placeholder: String, text: Binding, icon: String? = nil, isFocused: Bool = false, onFocusChange: @escaping (Bool) -> Void = { _ in } ) -> InputFieldView { InputFieldView( title: title, isRequired: isRequired, placeholder: placeholder, text: text, icon: icon, isSecure: true, isFocused: isFocused, onFocusChange: onFocusChange ) } } #Preview { VStack(spacing: 16) { InputFieldView.text( title: NSLocalizedString("username", comment: "Username"), isRequired: true, placeholder: NSLocalizedString("enter_username", comment: "Please enter username"), text: .constant(""), icon: "person" ) InputFieldView.email( title: NSLocalizedString("email_address", comment: "Email address"), isRequired: true, placeholder: "user@example.com", text: .constant(""), icon: "envelope" ) InputFieldView.phone( title: NSLocalizedString("phone_number", comment: "Phone number"), isRequired: true, placeholder: "+1 (555) 123-4567", text: .constant(""), icon: "phone" ) InputFieldView.password( title: NSLocalizedString("password", comment: "Password"), isRequired: true, placeholder: NSLocalizedString("enter_password", comment: "Please enter password"), text: .constant(""), icon: "lock" ) } .padding() }