فهرست منبع

feat(ui/title): 优化记录标题格式与编辑框后缀高亮选中体验

bob.yuxinyang 1 ماه پیش
والد
کامیت
507a364859
2فایلهای تغییر یافته به همراه85 افزوده شده و 16 حذف شده
  1. 1 1
      CelestiaTrace/Views/Home/HomeView.swift
  2. 84 15
      CelestiaTrace/Views/Recording/ActiveRecordingView.swift

+ 1 - 1
CelestiaTrace/Views/Home/HomeView.swift

@@ -161,7 +161,7 @@ struct HomeView: View {
     private func createSessionAndNavigate(source: RecordingSourceChoice) {
         let formatter = DateFormatter()
         formatter.dateFormat = "yyyyMMdd_HHmm"
-        let title = "现场记录_\(formatter.string(from: Date()))"
+        let title = "\(formatter.string(from: Date()))_现场记录"
 
         let session = CelestiaSession(title: title)
         modelContext.insert(session)

+ 84 - 15
CelestiaTrace/Views/Recording/ActiveRecordingView.swift

@@ -1,5 +1,6 @@
 import SwiftUI
 import SwiftData
+import UIKit
 
 // MARK: - ActiveRecordingView
 /// The live recording screen showing real-time waveform, elapsed time,
@@ -717,8 +718,6 @@ struct RecordNameEditorSheet: View {
     let onSave: () -> Void
     let onCancel: () -> Void
 
-    @FocusState private var isRecordNameFocused: Bool
-
     var body: some View {
         NavigationStack {
             ZStack {
@@ -730,20 +729,16 @@ struct RecordNameEditorSheet: View {
                         .foregroundStyle(Color.secondary)
                         .tracking(1.4)
 
-                    TextField("输入记录名称", text: $recordName)
-                        .focused($isRecordNameFocused)
-                        .font(.system(size: 18, weight: .semibold))
-                        .foregroundStyle(Color.primary)
-                        .textInputAutocapitalization(.never)
-                        .autocorrectionDisabled()
-                        .submitLabel(.done)
+                    SuffixSelectingTextField(
+                        placeholder: "输入记录名称",
+                        text: $recordName,
+                        selectedSuffix: "现场记录",
+                        onSubmit: onSave
+                    )
                         .padding(.horizontal, 14)
                         .padding(.vertical, 12)
                         .background(Color.cardBackground.opacity(0.5))
                         .businessBorder(cornerRadius: 8)
-                        .onSubmit {
-                            onSave()
-                        }
 
                     Spacer()
                 }
@@ -766,10 +761,84 @@ struct RecordNameEditorSheet: View {
         .presentationDetents([.height(190)])
         .presentationDragIndicator(.visible)
         .presentationBackground(Color.spaceBlack)
-        .onAppear {
-            DispatchQueue.main.async {
-                isRecordNameFocused = true
+    }
+}
+
+private struct SuffixSelectingTextField: UIViewRepresentable {
+    let placeholder: String
+    @Binding var text: String
+    let selectedSuffix: String
+    let onSubmit: () -> Void
+
+    func makeCoordinator() -> Coordinator {
+        Coordinator(text: $text, selectedSuffix: selectedSuffix, onSubmit: onSubmit)
+    }
+
+    func makeUIView(context: Context) -> UITextField {
+        let textField = UITextField()
+        textField.placeholder = placeholder
+        textField.text = text
+        textField.font = .systemFont(ofSize: 18, weight: .semibold)
+        textField.textColor = .label
+        textField.tintColor = UIColor(Color.accentColor)
+        textField.autocapitalizationType = .none
+        textField.autocorrectionType = .no
+        textField.returnKeyType = .done
+        textField.delegate = context.coordinator
+        textField.addTarget(
+            context.coordinator,
+            action: #selector(Coordinator.textDidChange(_:)),
+            for: .editingChanged
+        )
+
+        DispatchQueue.main.async {
+            textField.becomeFirstResponder()
+            context.coordinator.selectSuffixIfNeeded(in: textField)
+        }
+        return textField
+    }
+
+    func updateUIView(_ textField: UITextField, context: Context) {
+        if textField.text != text {
+            textField.text = text
+        }
+    }
+
+    final class Coordinator: NSObject, UITextFieldDelegate {
+        @Binding private var text: String
+        private let selectedSuffix: String
+        private let onSubmit: () -> Void
+        private var hasAppliedInitialSelection = false
+
+        init(text: Binding<String>, selectedSuffix: String, onSubmit: @escaping () -> Void) {
+            _text = text
+            self.selectedSuffix = selectedSuffix
+            self.onSubmit = onSubmit
+        }
+
+        @objc func textDidChange(_ textField: UITextField) {
+            text = textField.text ?? ""
+        }
+
+        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+            onSubmit()
+            return true
+        }
+
+        func selectSuffixIfNeeded(in textField: UITextField) {
+            guard !hasAppliedInitialSelection else { return }
+            hasAppliedInitialSelection = true
+
+            let fullText = textField.text ?? ""
+            guard fullText.hasSuffix(selectedSuffix),
+                  let start = textField.position(
+                    from: textField.endOfDocument,
+                    offset: -selectedSuffix.utf16.count
+                  ),
+                  let range = textField.textRange(from: start, to: textField.endOfDocument) else {
+                return
             }
+            textField.selectedTextRange = range
         }
     }
 }