You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
5.1 KiB
163 lines
5.1 KiB
import SwiftUI
|
|
|
|
// MARK: - 电话输入组件
|
|
struct PhoneInputView: View {
|
|
@Binding var phoneNumber: String
|
|
@Binding var message: String
|
|
let inputType: PhoneInputType
|
|
@FocusState var focusedField: PhoneField?
|
|
|
|
// 电话输入类型枚举
|
|
enum PhoneInputType: String, CaseIterable {
|
|
case phone = "Phone"
|
|
case sms = "SMS"
|
|
|
|
var displayName: String {
|
|
switch self {
|
|
case .phone: return "电话"
|
|
case .sms: return "短信"
|
|
}
|
|
}
|
|
|
|
var icon: String {
|
|
switch self {
|
|
case .phone: return "phone"
|
|
case .sms: return "message"
|
|
}
|
|
}
|
|
|
|
var placeholder: String {
|
|
switch self {
|
|
case .phone: return "+1 (555) 123-4567"
|
|
case .sms: return "输入短信内容"
|
|
}
|
|
}
|
|
|
|
var hint: String {
|
|
switch self {
|
|
case .phone: return "输入电话号码,支持国际格式"
|
|
case .sms: return "输入短信内容,将生成可发送的链接"
|
|
}
|
|
}
|
|
}
|
|
|
|
// 电话字段枚举
|
|
enum PhoneField: Hashable {
|
|
case phoneNumber, message
|
|
}
|
|
|
|
var body: some View {
|
|
VStack(spacing: 16) {
|
|
// 类型信息
|
|
HStack {
|
|
Image(systemName: inputType.icon)
|
|
.font(.title2)
|
|
.foregroundColor(.blue)
|
|
|
|
VStack(alignment: .leading, spacing: 2) {
|
|
Text(inputType.displayName)
|
|
.font(.headline)
|
|
.foregroundColor(.primary)
|
|
|
|
Text(inputType.hint)
|
|
.font(.caption)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
|
|
Spacer()
|
|
}
|
|
.padding(.horizontal, 12)
|
|
.padding(.vertical, 8)
|
|
.background(
|
|
RoundedRectangle(cornerRadius: 8)
|
|
.fill(Color.blue.opacity(0.1))
|
|
)
|
|
|
|
// 电话号码 (必填)
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
HStack {
|
|
Text("电话号码")
|
|
.font(.subheadline)
|
|
.foregroundColor(.primary)
|
|
Text("*")
|
|
.foregroundColor(.red)
|
|
Spacer()
|
|
}
|
|
|
|
TextField("+1 (555) 123-4567", text: $phoneNumber)
|
|
.textFieldStyle(RoundedBorderTextFieldStyle())
|
|
.keyboardType(.phonePad)
|
|
.focused($focusedField, equals: .phoneNumber)
|
|
}
|
|
|
|
// 短信内容 (仅SMS类型)
|
|
if inputType == .sms {
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
HStack {
|
|
Text("短信内容")
|
|
.font(.subheadline)
|
|
.foregroundColor(.primary)
|
|
Spacer()
|
|
}
|
|
|
|
TextField("输入短信内容", text: $message)
|
|
.textFieldStyle(RoundedBorderTextFieldStyle())
|
|
.focused($focusedField, equals: .message)
|
|
}
|
|
}
|
|
|
|
// 格式说明
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
HStack {
|
|
Image(systemName: "info.circle")
|
|
.font(.caption)
|
|
.foregroundColor(.blue)
|
|
|
|
Text("格式说明")
|
|
.font(.caption)
|
|
.foregroundColor(.primary)
|
|
|
|
Spacer()
|
|
}
|
|
|
|
Text(getFormatHint())
|
|
.font(.caption)
|
|
.foregroundColor(.secondary)
|
|
.lineLimit(nil)
|
|
}
|
|
.padding(.horizontal, 12)
|
|
.padding(.vertical, 8)
|
|
.background(
|
|
RoundedRectangle(cornerRadius: 8)
|
|
.fill(Color.blue.opacity(0.1))
|
|
)
|
|
}
|
|
.toolbar {
|
|
ToolbarItemGroup(placement: .keyboard) {
|
|
Spacer()
|
|
Button("完成") {
|
|
focusedField = nil
|
|
}
|
|
.foregroundColor(.blue)
|
|
.font(.system(size: 16, weight: .medium))
|
|
}
|
|
}
|
|
}
|
|
|
|
private func getFormatHint() -> String {
|
|
switch inputType {
|
|
case .phone:
|
|
return "• 支持国际格式:+1 (555) 123-4567\n• 或本地格式:(555) 123-4567\n• 将生成 tel: 链接"
|
|
case .sms:
|
|
return "• 输入电话号码和短信内容\n• 将生成 SMSTO: 链接\n• 用户点击可直接发送短信"
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
PhoneInputView(
|
|
phoneNumber: .constant(""),
|
|
message: .constant(""),
|
|
inputType: .phone
|
|
)
|
|
} |