import SwiftUI // MARK: - Email输入组件 struct EmailInputView: View { @Binding var emailAddress: String @Binding var emailSubject: String @Binding var emailBody: String @Binding var emailCc: String @Binding var emailBcc: String @FocusState var focusedEmailField: EmailField? // Email字段枚举 enum EmailField: Hashable { case address, subject, body, cc, bcc } var body: some View { VStack(spacing: 16) { // Email地址 (必填) VStack(alignment: .leading, spacing: 8) { HStack { Text("邮箱地址") .font(.subheadline) .foregroundColor(.primary) Text("*") .foregroundColor(.red) Spacer() } TextField("user@example.com", text: $emailAddress) .textFieldStyle(RoundedBorderTextFieldStyle()) .keyboardType(.emailAddress) .autocapitalization(.none) .focused($focusedEmailField, equals: .address) } // 主题 (必填) VStack(alignment: .leading, spacing: 8) { HStack { Text("主题") .font(.subheadline) .foregroundColor(.primary) Text("*") .foregroundColor(.red) Spacer() } TextField("邮件主题", text: $emailSubject) .textFieldStyle(RoundedBorderTextFieldStyle()) .focused($focusedEmailField, equals: .subject) } // 正文 (必填) VStack(alignment: .leading, spacing: 8) { HStack { Text("正文") .font(.subheadline) .foregroundColor(.primary) Text("*") .foregroundColor(.red) Spacer() } ZStack { TextEditor(text: $emailBody) .frame(minHeight: 120) .padding(8) .background(Color(.systemBackground)) .cornerRadius(8) .overlay( RoundedRectangle(cornerRadius: 8) .stroke(focusedEmailField == .body ? Color.blue : Color(.systemGray4), lineWidth: 1) ) .focused($focusedEmailField, equals: .body) .onChange(of: emailBody) { newValue in // 限制最大字符数为1200 if newValue.count > 1200 { emailBody = String(newValue.prefix(1200)) } } // 占位符文本 if emailBody.isEmpty && focusedEmailField != .body { VStack { HStack { Text("输入邮件正文内容...") .foregroundColor(.secondary) .font(.body) Spacer() } Spacer() } .padding(16) .allowsHitTesting(false) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) } } // 字符计数 HStack { Spacer() Text("\(emailBody.count)/1200") .font(.caption) .foregroundColor(emailBody.count >= 1200 ? .orange : .secondary) } } // CC地址 (可选) VStack(alignment: .leading, spacing: 8) { HStack { Text("抄送地址") .font(.subheadline) .foregroundColor(.primary) Spacer() } TextField("cc@example.com", text: $emailCc) .textFieldStyle(RoundedBorderTextFieldStyle()) .keyboardType(.emailAddress) .autocapitalization(.none) .focused($focusedEmailField, equals: .cc) } // BCC地址 (可选) VStack(alignment: .leading, spacing: 8) { HStack { Text("密送地址") .font(.subheadline) .foregroundColor(.primary) Spacer() } TextField("bcc@example.com", text: $emailBcc) .textFieldStyle(RoundedBorderTextFieldStyle()) .keyboardType(.emailAddress) .autocapitalization(.none) .focused($focusedEmailField, equals: .bcc) } } .toolbar { ToolbarItemGroup(placement: .keyboard) { Spacer() Button("完成") { focusedEmailField = nil } .foregroundColor(.blue) .font(.system(size: 16, weight: .medium)) } } } } #Preview { EmailInputView( emailAddress: .constant(""), emailSubject: .constant(""), emailBody: .constant(""), emailCc: .constant(""), emailBcc: .constant("") ) }