新的 SwiftUI 框架似乎没有提供内置的搜索栏组件。我应该使用 UISearchController 并以某种方式包装它,还是应该使用简单的文本字段并根据文本字段输入更新数据?
编辑:当前的解决方法是使用 TextField
作为搜索栏。它运行良好,但没有搜索图标
import SwiftUI
struct Search : View {
let array = ["John","Lena","Steve","Chris","Catalina"]
@State private var searchText = ""
var body: some View {
NavigationView{
List{
TextField("Type your search",text: $searchText)
.textFieldStyle(RoundedBorderTextFieldStyle())
ForEach(array.filter{$0.hasPrefix(searchText) || searchText == ""}, id:\.self){searchText in
Text(searchText)
}
}
.navigationBarTitle(Text("Search"))
}
}
}
struct Search_Previews : PreviewProvider {
static var previews: some View {
Search()
}
}
更新到 Xcode 11.1
最佳答案
这是一个纯 swiftUI 版本,基于 Antoine Weber's回答他上面的问题以及我在 this blog 中发现的内容和 this gist .它包含
在列表中拖动时退出键盘可以使用以下these answers UIApplication 窗口上的方法来实现.为了更容易处理,我在 UIApplication 上创建了一个扩展,并为此扩展创建了 View 修饰符,最后为 View 创建了一个扩展:
extension UIApplication {
func endEditing(_ force: Bool) {
self.windows
.filter{$0.isKeyWindow}
.first?
.endEditing(force)
}
}
struct ResignKeyboardOnDragGesture: ViewModifier {
var gesture = DragGesture().onChanged{_ in
UIApplication.shared.endEditing(true)
}
func body(content: Content) -> some View {
content.gesture(gesture)
}
}
extension View {
func resignKeyboardOnDragGesture() -> some View {
return modifier(ResignKeyboardOnDragGesture())
}
}
因此,退出键盘的最终修饰符只是一个必须放在列表中的修饰符,如下所示:
List {
ForEach(...) {
//...
}
}
.resignKeyboardOnDragGesture()
带有示例名称列表的搜索栏的完整 swiftUI 项目代码如下。您可以将其粘贴到新的 swiftUI 项目的 ContentView.swift 中并使用它。
import SwiftUI
struct ContentView: View {
let array = ["Peter", "Paul", "Mary", "Anna-Lena", "George", "John", "Greg", "Thomas", "Robert", "Bernie", "Mike", "Benno", "Hugo", "Miles", "Michael", "Mikel", "Tim", "Tom", "Lottie", "Lorrie", "Barbara"]
@State private var searchText = ""
@State private var showCancelButton: Bool = false
var body: some View {
NavigationView {
VStack {
// Search view
HStack {
HStack {
Image(systemName: "magnifyingglass")
TextField("search", text: $searchText, onEditingChanged: { isEditing in
self.showCancelButton = true
}, onCommit: {
print("onCommit")
}).foregroundColor(.primary)
Button(action: {
self.searchText = ""
}) {
Image(systemName: "xmark.circle.fill").opacity(searchText == "" ? 0 : 1)
}
}
.padding(EdgeInsets(top: 8, leading: 6, bottom: 8, trailing: 6))
.foregroundColor(.secondary)
.background(Color(.secondarySystemBackground))
.cornerRadius(10.0)
if showCancelButton {
Button("Cancel") {
UIApplication.shared.endEditing(true) // this must be placed before the other commands here
self.searchText = ""
self.showCancelButton = false
}
.foregroundColor(Color(.systemBlue))
}
}
.padding(.horizontal)
.navigationBarHidden(showCancelButton) // .animation(.default) // animation does not work properly
List {
// Filtered list of names
ForEach(array.filter{$0.hasPrefix(searchText) || searchText == ""}, id:\.self) {
searchText in Text(searchText)
}
}
.navigationBarTitle(Text("Search"))
.resignKeyboardOnDragGesture()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
.environment(\.colorScheme, .light)
ContentView()
.environment(\.colorScheme, .dark)
}
}
}
extension UIApplication {
func endEditing(_ force: Bool) {
self.windows
.filter{$0.isKeyWindow}
.first?
.endEditing(force)
}
}
struct ResignKeyboardOnDragGesture: ViewModifier {
var gesture = DragGesture().onChanged{_ in
UIApplication.shared.endEditing(true)
}
func body(content: Content) -> some View {
content.gesture(gesture)
}
}
extension View {
func resignKeyboardOnDragGesture() -> some View {
return modifier(ResignKeyboardOnDragGesture())
}
}
搜索栏的最终结果,最初显示时如下所示
当搜索栏像这样编辑时:
在行动:
关于swiftui - 如何使用 SwiftUI 显示搜索栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56490963/