Reputation: 41
I'm trying to dismiss the keyboard and resign focus state on a .searchable field of a NavigationStack when tapped away from the keyboard or when the user taps the Search button on the keyboard. I used FocusedState var to dismiss it, which works with TextField but here it probably works differently. To clarify - I basically want to replicate the behaviour of the Cancel button that show next to the search field of the NavigationStack .searchable. Any idea how to do it? My current approach is below.
import SwiftUI
struct ContentView: View {
@State private var searchLocation = ""
private let vm = ViewModel()
@FocusState private var typingLocation : Bool
var body: some View {
NavigationStack {
GeometryReader { geo in
VStack {
HStack {
Spacer()
VStack {
Text(vm.weather.locationName)
.font(.title)
.foregroundStyle(.primary)
Text(vm.weather.temperature)
.font(.title2)
.foregroundStyle(.secondary)
}
Spacer()
VStack {
Image(systemName: "sun.max.fill")
.foregroundStyle(.yellow)
.font(.largeTitle)
.symbolEffect(.breathe)
Text(vm.weather.conditions)
.font(.title2)
.foregroundStyle(.secondary)
}
Spacer()
}
.padding()
HStack {
ScrollView {
LazyVGrid(columns: [GridItem(), GridItem()]) {
ForEach(0..<10) { index in
VStack {
HStack {
Text("Wind")
Image(systemName: "wind")
.symbolEffect(.wiggle)
Spacer()
Image(systemName: "arrow.up")
.rotationEffect(.degrees(vm.weather.windDirection ?? 0))
}
.foregroundStyle(.secondary)
.padding([.leading, .top, .trailing], 15)
.padding(.bottom)
Text(vm.weather.windSpeed)
.font(.largeTitle)
Spacer()
}
.frame(width: geo.size.width/2.25, height: 150)
.background(.ultraThinMaterial)
.clipShape(.rect(cornerRadius: 20))
.padding(.bottom, 3)
}
}
}
}
}
.onTapGesture{
typingLocation = false
}
.padding()
}
.background(.blue.opacity(0.4))
.navigationTitle("Athlete Weather")
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button("Settings", systemImage: "gearshape") {
Task {
await vm.getWeather(for: "Liberec")
}
}
.tint(.primary)
}
ToolbarItem(placement: .topBarTrailing) {
Button("Sports", systemImage: "figure.run.square.stack") {
}
.tint(.primary)
}
}
}
.searchable(text: $searchLocation, prompt: "Search Location")
.focused($typingLocation)
.onSubmit(of: .search) {
Task{
await vm.getWeather(for: searchLocation)
}
}
// .preferredColorScheme(.dark)
}
}
#Preview {
ContentView()
}
Upvotes: 0
Views: 20