Home > Software engineering >  How to combine searchable text in SwiftUI and opening a new View with the found text string?
How to combine searchable text in SwiftUI and opening a new View with the found text string?

Time:08-16

I'm trying to make an app that offers a choice. Depending on the color that a user selects, a new View appears. What it will be there, depends on a text parameter.

I wish to make it via search bar in SwiftUI, offering some options. A user starts typing, and available choices appear at the screen.

This is my code, and it does not work. Regardless of what I select, it only shows what I selected, and "Go" button is never available (looks like a gray text at the bottom of the screen).

What is wrong here? Thank you!

struct ContentView: View {
    let colors = ["Blue", "Cyan", "Teal", "Mint", "Green", "Yellow", "Orange", "Red", "Pink", "Purple", "Indigo"]
    
    var filteredColors: [String] { // 1
        if queryString.isEmpty {
            return colors
        } else {
            return colors.filter { $0.localizedCaseInsensitiveContains(queryString) }
        }
    }
    
    @State private var queryString = ""
    @State private var goToSecondView = false
    
    
    var body: some View {
        NavigationView {
            List(filteredColors, id: \.self) { color in
                Text(color)
            }
            .navigationTitle("Colors")
            .searchable(text: $queryString, prompt: "Color Search", suggestions: {
                ForEach(colors.filter { $0.localizedCaseInsensitiveContains(queryString) } , id: \.self) { suggestion in
                    Text(suggestion)
                        .searchCompletion(suggestion)
                }
            })
            .onSubmit(of: .search) { // 1
                print("submit")
                goToSecondView = true
            }
        }
        NavigationLink {
            if goToSecondView {
                SecondView(querystring: queryString)
            }
        } label: {
            Text("Go")
        }
    }
}

struct SecondView : View {
    var querystring : String
    var body : some View {
        Text(querystring)
    }
}

screenshot

CodePudding user response:

I suppose you wanted to activate navigation link programmatically on submit, so here is a possible approach:

.onSubmit(of: .search) { // 1
    print("submit")
    goToSecondView = true
}
.background(
    NavigationLink(isActive: $goToSecondView) {   // << here !!
        SecondView(querystring: queryString)
    } label: {
        EmptyView()
    }
)

CodePudding user response:

You could just make the selected list item itself the navigation link (and get rid of onSubmit modifier) and go to SecondView on selection of color

NavigationView {
    List(filteredColors, id: \.self) { color in
        NavigationLink {
            SecondView(querystring: color)
        } label: {
            Text(color)
        }
    }
    /* ... */
}
  • Related