// // FormatterView.swift // Note // // Created by fish on 2026/7/12. // import SwiftUI struct FormatterView: View { @State private var inputText: String = "" @State private var showEmptyAlert: Bool = false @State private var showCopied: Bool = false var body: some View { NavigationStack { VStack(spacing: 0) { headerView inputArea .frame(maxHeight: .infinity) actionArea } .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) } } .navigationBarHidden(true) } } private var headerView: some View { HStack { Text("文案格式化") .font(.largeTitle.bold()) .foregroundStyle(.primary) Spacer() if !inputText.isEmpty { Button(action: copyText) { Image(systemName: "doc.on.doc") } .font(.title3) } } .frame(maxWidth: .infinity, minHeight: 44) .padding(.horizontal) .padding(.top, 8) .padding(.bottom, 8) .background(Color(.systemGroupedBackground)) .contentShape(Rectangle()) .onTapGesture { dismissKeyboard() } } private var inputArea: some View { VStack(alignment: .leading, spacing: 8) { Text("输入") .font(.subheadline) .foregroundStyle(.secondary) .padding(.horizontal) TextEditor(text: $inputText) .frame(maxWidth: .infinity, maxHeight: .infinity) .padding(12) .background(Color(.systemBackground)) .cornerRadius(12) .overlay( RoundedRectangle(cornerRadius: 12) .stroke(Color(.systemGray4), lineWidth: 1) ) .padding(.horizontal) .toolbar { ToolbarItemGroup(placement: .keyboard) { Spacer() Button("完成") { dismissKeyboard() } } } Text("粘贴需要格式化的文案") .font(.subheadline) .foregroundStyle(.secondary) .padding(.horizontal) } .padding(.vertical, 8) } private var actionArea: some View { Button(action: formatText) { Label("格式化", systemImage: "wand.and.stars") .font(.headline) .frame(maxWidth: .infinity) .padding() .background(Color(.systemBackground)) .foregroundStyle(Color.accentColor) .cornerRadius(12) } .padding() .background(Color(.systemGroupedBackground)) } 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 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: "## 三、工作方面") inputText = content dismissKeyboard() } private func copyText() { UIPasteboard.general.string = inputText withAnimation { showCopied = true } DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { withAnimation { showCopied = false } } } } #Preview { FormatterView() }