ScrollView
(可能还带有List
,但我没有确认),您可以使用 UIScrollView
appearance
,这将影响所有的 ScrollViews。UIScrollView.appearance().keyboardDismissMode = .onDrag
截至目前,自iOS 16测试版开始,我们有了一个新的修饰符scrollDismissesKeyboard()
,可以完全满足您的需求。
在您的示例中应该如下所示
struct ContentView: View {
@State var text: String = ""
var items = 1...100
var body: some View {
List {
TextField("Search", text: $text)
Section {
ForEach(items.filter({"\($0)".contains(text)}), id: \.self) { (i) in
Text("option \(i)")
}
}
}
.scrollDismissesKeyboard(.interactively) // <<-- Put this line
}
}
scrollDismissesKeyboard()
修改器有一个参数,用于确定键盘退出规则。以下是可能的取值:
.automatic
:基于滚动上下文来取消键盘。.immediately
:任何滚动发生时立即关闭键盘。.interactively
:键盘将随用户手势移动/消失。.never
:用户滚动时键盘永远不会消失。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版本的搜索栏,可能对你很有趣。你可以在这个回答中找到它。
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
let window = windowScene?.windows.first
window?.endEditing(force)
- user3687284Form {
...
}.gesture(DragGesture().onChanged { _ in
UIApplication.shared.windows.forEach { $0.endEditing(false) }
})
Slider
组件。 - Juraj Blahunka@FocusState
包装器与.focused()
TextField
修饰符结合使用时非常有用。
struct ContentView: View {
@FocusState private var focusedSearchField: Bool
@State var text:String = ""
var items = 1...100
var body: some View {
VStack {
List {
TextField("Search", text: $text)
.focused($focusedSearchField)
Section{
ForEach(items.filter({"\($0)".contains(text)}),id: \.self){(i) in
Text("option \(i)")
}
}
} // to also allow swipes on items (theoretically)
.simultaneousGesture(DragGesture().onChanged({ _ in
focusedSearchField = false
}))
.onTapGesture { // dissmis on tap as well
focusedSearchField = false
}
}
}
}
struct EndEditingKeyboardOnDragGesture: ViewModifier {
func body(content: Content) -> some View {
content.highPriorityGesture (
DragGesture().onChanged { _ in
UIApplication.shared.endEditing()
}
)
}
}
extension View {
func endEditingKeyboardOnDragGesture() -> some View {
return modifier(EndEditingKeyboardOnDragGesture())
}
}
List
,我已经测试过了,可能也适用于其他可滚动视图。我猜这是因为List
是ScrollView
的子类。 - qsmy