Search code examples
swiftswiftuiswiftui-view

Override the functionality of the button from another View?


I got a re-usable searchbar in a separate view that looks like this:


struct SearchBar: View {
    
    @Binding var searchText: String
    @Binding var isSearching: Bool
    
    var body: some View {
        HStack {
            HStack {
                TextField("Search terms here", text: $searchText)
            }
            .onTapGesture(perform: {
                isSearching = true
            })
            .overlay(
                HStack {
                    Image(systemName: "magnifyingglass")
                    
                    if isSearching {
                        Button(action: { searchText = "" }, label: {
                            Image(systemName: "xmark.circle.fill")     
                        })
                    }   
                }
            )
            if isSearching {
                Button(action: {
                    isSearching = false
                    searchText = ""
                    
                }, label: {
                    Text("Cancel")
                        
                })
            }
            
        }
    }
}

And I'm using the SearchBar in multiple views, like this:

SearchBar(searchText: $textFieldSearch, isSearching: $isSearching)

Is there a way to override/append the functionality of the cancel button:

Button(action: {
   isSearching = false
   searchText = ""
   // pass more functionality here dynamically
 }, 
  label: {
  Text("Cancel")   
})

In some Views, I need to do some additional stuff besides clearing the searchText field and setting isSearching to false.


Solution

  • You can use closure. Here I created one cancel button closure action and set it as optional.

    struct SearchBar: View {
        
        @Binding var searchText: String
        @Binding var isSearching: Bool
        var cancel: (() -> Void)? // <== Here
        
        var body: some View {
            HStack {
                HStack {
                    TextField("Search terms here", text: $searchText)
                }
                .onTapGesture(perform: {
                    isSearching = true
                })
                .overlay(
                    HStack {
                        Image(systemName: "magnifyingglass")
                        
                        if isSearching {
                            Button(action: { searchText = "" }, label: {
                                Image(systemName: "xmark.circle.fill")
                            })
                        }
                    }
                )
                if isSearching {
                    Button(action: {
                        isSearching = false
                        searchText = ""
                        cancel?() // <== Here
                    }, label: {
                        Text("Cancel")
                        
                    })
                }
                
            }
        }
    }
    
    

    Usage

    SearchBar(searchText: $textFieldSearch, isSearching: $isSearching)
    SearchBar(searchText: $textFieldSearch, isSearching: $isSearching) {
        // Cancel Action
    }