History
Loading...
Loading...
September 23, 2025
onEditingChanged parameter to trigger immediate actions when users start or stop editing. This callback fires with true when editing begins and false when it ends, perfect for showing/hiding validation hints or triggering auto-save functionality without waiting for commits.This pattern implements debounced search by canceling previous search tasks when new input arrives, only executing searches after a 300ms delay. The Task-based approach automatically handles view lifecycle and prevents unnecessary API calls during rapid typing.
struct SearchView: View {
@State private var searchText = ""
@State private var results: [String] = []
@State private var searchTask: Task<Void, Never>?
var body: some View {
VStack {
TextField("Search...", text: $searchText)
.textFieldStyle(.roundedBorder)
.onChange(of: searchText) { _, newValue in
searchTask?.cancel()
searchTask = Task {
try? await Task.sleep(nanoseconds: 300_000_000)
if !Task.isCancelled {
await performSearch(query: newValue)
}
}
}
List(results, id: \.self) { result in
Text(result)
}
}
}
private func performSearch(query: String) async {
// Simulate API call
results = query.isEmpty ? [] : ["Result 1", "Result 2"]
}
}Debouncing reduces server load, improves performance, and provides better UX by avoiding flickering results. Using Swift's structured concurrency with Task ensures proper cancellation and memory management, while the 300ms delay strikes the right balance between responsiveness and efficiency.