// // FormatterView.swift // Note // // Created by fish on 2026/7/12. // import SwiftUI struct FormatterView: View { @State private var inputText: String = "" @State private var outputText: String = "" @State private var showEmptyAlert: Bool = false @State private var showCopied: Bool = false var body: some View { NavigationStack { List { inputSection actionSection if !outputText.isEmpty { resultSection } } .listStyle(.insetGrouped) .navigationTitle("文案格式化") .background(Color(.systemGroupedBackground).ignoresSafeArea()) .alert("提示", isPresented: $showEmptyAlert) { Button("确定", role: .cancel) {} } message: { Text("请输入需要格式化的文案") } .overlay { if showCopied { VStack { Spacer() Text("已复制") .font(.subheadline) .padding(.horizontal, 16) .padding(.vertical, 8) .background(Color.black.opacity(0.75)) .foregroundStyle(.white) .cornerRadius(20) .padding(.bottom, 32) } .transition(.opacity) } } } } private var inputSection: some View { Section { TextEditor(text: $inputText) .frame(minHeight: 160) .scrollContentBackground(.hidden) .background(Color(.secondarySystemGroupedBackground)) .toolbar { ToolbarItemGroup(placement: .keyboard) { Spacer() Button("完成") { dismissKeyboard() } } } } header: { Text("输入") } footer: { Text("粘贴需要格式化的文案") } } private var actionSection: some View { Section { Button(action: formatText) { HStack { Spacer() Label("格式化", systemImage: "wand.and.stars") .font(.headline) Spacer() } } } } private var resultSection: some View { Section { TextEditor(text: .constant(outputText)) .frame(minHeight: 160) .scrollContentBackground(.hidden) .background(Color(.secondarySystemGroupedBackground)) } header: { HStack { Text("格式化结果") Spacer() Button(action: copyOutput) { Image(systemName: "doc.on.doc") } .font(.subheadline) } } } private func dismissKeyboard() { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } private func formatText() { if inputText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { showEmptyAlert = true outputText = "" return } var content = inputText // 去 # content = content.replacingOccurrences(of: "# ", with: "") content = content.replacingOccurrences(of: "#", with: "") // 将 ; 转为句号 content = content.replacingOccurrences(of: ";", with: "。") // 将 ; 转为句号 content = content.replacingOccurrences(of: ";", with: "。") // 将 . 转为句号 content = content.replacingOccurrences(of: ".", with: "。") // 将 ( 转为 ( content = content.replacingOccurrences(of: "(", with: "(") // 将 ) 转为 ) content = content.replacingOccurrences(of: ")", with: ")") // 将 ? 转为 ? content = content.replacingOccurrences(of: "?", with: "?") // 将 , 转为 , content = content.replacingOccurrences(of: ",", with: ",") // 将 : 转为 : content = content.replacingOccurrences(of: ":", with: ":") // 将 日星期 转为 日 星期 content = content.replacingOccurrences(of: "日星期", with: "日 星期") // 在第一行插入 # content = "# " + content // 标题设置 content = content.replacingOccurrences(of: "一、生活方面", with: "## 一、生活方面") content = content.replacingOccurrences(of: "二、交易方面", with: "## 二、交易方面") content = content.replacingOccurrences(of: "三、工作方面", with: "## 三、工作方面") outputText = content dismissKeyboard() } private func copyOutput() { UIPasteboard.general.string = outputText withAnimation { showCopied = true } DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { withAnimation { showCopied = false } } } } #Preview { FormatterView() }