eatom
eatom

Reputation: 41

Dismiss keyboard and resigns focus state on .searchable

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

Answers (0)

Related Questions