#swift #swiftui #swiftui-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)
Есть ли способ переопределить/добавить функциональность кнопки «Отмена»:
Button(action: {
isSearching = false
searchText = ""
// pass more functionality here dynamically
},
label: {
Text("Cancel")
})
В некоторых представлениях мне нужно сделать некоторые дополнительные вещи, помимо очистки searchText
поля и установки isSearching
значения false.
Ответ №1:
Вы можете использовать закрытие. Здесь я создал одно действие закрытия кнопки отмены и установил его как необязательное.
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
}
Комментарии:
1. ->>
cancel?()
, Как используется эта часть? Допустим, вы добавляете закрытиеSearchBar
, как показано, как должен выглядеть синтаксис внутриButton(action:...{})
?2. Сначала я объявляю закрытие отмены в представлении и вызываю его с помощью действия кнопки отмены. Закрытие-это единственное время выполнения функции, но без имени.
3. Хотя я не понимаю этой
cancel?()
части4. Не могли бы вы, пожалуйста, уточнить у меня, хотите ли вы передавать данные из другого представления в представление поиска или из представления поиска в другое представление?
5. Хорошо, в одном представлении (и только в одном конкретном представлении), когда пользователь нажимает «Отмена», он должен вызвать вызываемую функцию
clearResults()
, которая просто вызывает API на мой сервер. Для всех других представлений, которые используют кнопку «отмена», мне нужна обычная функциональность: настройкаisSearching = false
иsearchText = ""
Ответ №2:
Если вам нужно дополнительное действие, вы можете ввести 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
}