v1.4.1Deployed

Vocabulary App

The updated SwiftUI source for the native vocabulary app. This release fixes the compilation error by replacing .foregroundColor(.quaternary) with .foregroundStyle(.quaternary), which is the correct modifier for hierarchical styles like .quaternary.

Source code

Swift · 319 lines

ContentView.swift
import SwiftUIimport UIKit // MARK: - Modelsstruct VocabularyWord: Identifiable, Codable, Equatable {    let id: UUID    let word: String    let translation: String    let dateAdded: Date        init(word: String, translation: String = "", dateAdded: Date = Date()) {        self.id = UUID()        self.word = word        self.translation = translation        self.dateAdded = dateAdded    }} // MARK: - App Stateclass AppState: ObservableObject {    @Published var savedWords: [VocabularyWord] = [        VocabularyWord(word: "Vintage", translation: "经典;复古", dateAdded: Date().addingTimeInterval(-3600)),        VocabularyWord(word: "Legacy", translation: "遗产;遗留", dateAdded: Date().addingTimeInterval(-1800)),        VocabularyWord(word: "Optimization", translation: "优化", dateAdded: Date())    ]        func addWord(_ word: String) {        let trimmed = word.trimmingCharacters(in: .whitespacesAndNewlines)        guard !trimmed.isEmpty else { return }        if !savedWords.contains(where: { $0.word.lowercased() == trimmed.lowercased() }) {            savedWords.insert(VocabularyWord(word: trimmed), at: 0)        }    }        func deleteWord(id: UUID) {        savedWords.removeAll { $0.id == id }    }        func deleteWords(at offsets: IndexSet, from filteredList: [VocabularyWord]) {        for index in offsets {            let wordId = filteredList[index].id            deleteWord(id: wordId)        }    }} // MARK: - Dictionary Wrapperstruct DictionaryLookupView: UIViewControllerRepresentable {    let word: String        func makeUIViewController(context: Context) -> UIReferenceLibraryViewController {        return UIReferenceLibraryViewController(term: word)    }        func updateUIViewController(_ uiViewController: UIReferenceLibraryViewController, context: Context) {}} // MARK: - Home Tabstruct HomeView: View {    @EnvironmentObject var state: AppState        var body: some View {        NavigationStack {            List {                Section {                    VStack(alignment: .leading, spacing: 12) {                        Text(currentDateString)                            .font(.headline)                            .foregroundColor(.secondary)                                                Text(greeting)                            .font(.system(size: 34, weight: .bold, design: .rounded))                                                Text("Welcome back to your vocabulary journey. Focus on your growth and keep expanding your horizons.")                            .font(.body)                            .foregroundColor(.secondary)                    }                    .padding(.vertical, 8)                }                                Section("Quick Stats") {                    HStack {                        Label("Words Saved", systemImage: "book.fill")                        Spacer()                        Text("\(state.savedWords.count)")                            .foregroundColor(.secondary)                    }                }            }            .navigationTitle("Home")        }    }        private var currentDateString: String {        let formatter = DateFormatter()        formatter.dateFormat = "EEEE, MMMM d, yyyy"        return formatter.string(from: Date())    }        private var greeting: String {        let hour = Calendar.current.component(.hour, from: Date())        if hour < 12 { return "Good Morning" }        if hour < 18 { return "Good Afternoon" }        return "Good Evening"    }} // MARK: - Search Tabstruct SearchView: View {    @EnvironmentObject var state: AppState    @State private var searchText = ""    @State private var showingLookup = false    @State private var lookupWord = ""        var body: some View {        NavigationStack {            Form {                Section {                    TextField("Enter word to lookup...", text: $searchText)                        .textInputAutocapitalization(.never)                        .disableAutocorrection(true)                        .submitLabel(.search)                        .onSubmit {                            performLookup()                        }                                        Button(action: performLookup) {                        Label("Lookup in System Dictionary", systemImage: "book.fill")                    }                    .disabled(searchText.trimmingCharacters(in: .whitespaces).isEmpty)                } header: {                    Text("Native Lookup")                }                                if !searchText.trimmingCharacters(in: .whitespaces).isEmpty {                    Section {                        Button(action: {                            state.addWord(searchText)                            searchText = ""                        }) {                            Label("Save to Library", systemImage: "plus.circle.fill")                        }                    }                }            }            .navigationTitle("Search")            .sheet(isPresented: $showingLookup) {                if !lookupWord.isEmpty {                    DictionaryLookupView(word: lookupWord)                        .ignoresSafeArea()                }            }        }    }        private func performLookup() {        let trimmed = searchText.trimmingCharacters(in: .whitespaces)        if !trimmed.isEmpty {            lookupWord = trimmed            showingLookup = true        }    }} // MARK: - Library Tabenum SortOption: String, CaseIterable, Identifiable {    case dateAdded = "Date Added"    case alphabetical = "Alphabetical"    var id: String { self.rawValue }} struct LibraryView: View {    @EnvironmentObject var state: AppState    @State private var librarySearch = ""    @State private var sortOption: SortOption = .dateAdded    @State private var selectedWordForLookup: VocabularyWord?        var filteredAndSortedWords: [VocabularyWord] {        var result = state.savedWords                if !librarySearch.isEmpty {            result = result.filter { $0.word.localizedCaseInsensitiveContains(librarySearch) }        }                switch sortOption {        case .dateAdded:            result.sort { $0.dateAdded > $1.dateAdded }        case .alphabetical:            result.sort { $0.word.localizedCaseInsensitiveCompare($1.word) == .orderedAscending }        }                return result    }        var body: some View {        NavigationStack {            List {                if filteredAndSortedWords.isEmpty {                    Text(librarySearch.isEmpty ? "No words saved yet." : "No results for \"\(librarySearch)\"")                        .foregroundColor(.secondary)                } else {                    ForEach(filteredAndSortedWords) { word in                        Button {                            selectedWordForLookup = word                        } label: {                            HStack {                                VStack(alignment: .leading) {                                    Text(word.word)                                        .font(.headline)                                        .foregroundColor(.primary)                                    if !word.translation.isEmpty {                                        Text(word.translation)                                            .font(.subheadline)                                            .foregroundColor(.secondary)                                    }                                }                                Spacer()                                Image(systemName: "chevron.right")                                    .font(.footnote.bold())                                    .foregroundStyle(.quaternary)                            }                        }                    }                    .onDelete { offsets in                        state.deleteWords(at: offsets, from: filteredAndSortedWords)                    }                }            }            .navigationTitle("Library")            .searchable(text: $librarySearch, placement: .navigationBarDrawer(displayMode: .always), prompt: "Search saved words")            .toolbar {                ToolbarItem(placement: .navigationBarTrailing) {                    Menu {                        Picker("Sort By", selection: $sortOption) {                            ForEach(SortOption.allCases) { option in                                Text(option.rawValue).tag(option)                            }                        }                    } label: {                        Label("Sort", systemImage: "arrow.up.arrow.down")                    }                }                ToolbarItem(placement: .navigationBarLeading) {                    EditButton()                }            }            .sheet(item: $selectedWordForLookup) { word in                DictionaryLookupView(word: word.word)                    .ignoresSafeArea()            }        }    }} // MARK: - Settings Tabstruct SettingsView: View {    @State private var icloudSync = true        var body: some View {        NavigationStack {            Form {                Section("Preferences") {                    Toggle("iCloud Sync", isOn: $icloudSync)                }                                Section("About") {                    HStack {                        Text("App Version")                        Spacer()                        Text("1.4.1")                            .foregroundColor(.secondary)                    }                                        Text("Optimized for iPad workflows using native system UI components and robust data management.")                        .font(.footnote)                        .foregroundColor(.secondary)                }            }            .navigationTitle("Settings")        }    }} // MARK: - Main Appstruct NativeVocabularyApp: View {    @StateObject private var state = AppState()        var body: some View {        TabView {            HomeView()                .tabItem {                    Label("Home", systemImage: "house.fill")                }                        SearchView()                .tabItem {                    Label("Search", systemImage: "magnifyingglass")                }                        LibraryView()                .tabItem {                    Label("Library", systemImage: "text.book.closed.fill")                }                        SettingsView()                .tabItem {                    Label("Settings", systemImage: "gear")                }        }        .environmentObject(state)    }} // MARK: - Entry Pointstruct ContentView: View {    var body: some View {        NativeVocabularyApp()    }}

What changed