从另一个视图覆盖按钮的功能?

Override the functionality of the button from another View?

我在单独的视图中获得了一个可重复使用的搜索栏,如下所示:


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")
                        
                })
            }
            
        }
    }
}

我在多个视图中使用 SearchBar,如下所示:

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

有没有办法override/append取消按钮的功能:

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

在某些视图中,除了清除 searchText 字段并将 isSearching 设置为 false 之外,我还需要做一些额外的事情。

你可以使用闭包。 这里我创建了一个取消按钮关闭动作并将其设置为可选。

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")
                    
                })
            }
            
        }
    }
}

用法

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

如果您需要附加 操作,那么您可以注入onCancel 副作用,例如

struct SearchBar: View {
    
    @Binding var searchText: String
    @Binding var isSearching: Bool
    var onCancel: () -> Void = {}     // << default does nothing

    ...

            if isSearching {
                Button(action: {
                    isSearching = false
                    searchText = ""
                    onCancel()            // << here !!
                }, label: {
                    Text("Cancel")
                    
                })
            }

并像您一样以默认方式使用或提供副作用,例如

SearchBar(searchText: $textFieldSearch, isSearching: $isSearching) {
  // side effect is here
}