如何在包含选择器的SwiftUI表单中隐藏键盘?

如何在包含选择器的SwiftUI表单中隐藏键盘?,swiftui,swiftui-form,Swiftui,Swiftui Form,我有一个SwiftUI表单,其中包含一个选择器、一个文本字段和一个文本: 结构ContentView:View{ var body:一些观点{ 形式{ 部分{ Pickerselection:$selection,label:label{ //填充选择器的代码 }.PickerStyle分段PickerStyle HStack{ text字段标题,text:$text 文本 } } } } } 上述代码将生成以下UI: 我能够轻松地在选择器中选择第二项,如下所示: 在下面,您可以看到我可以通过点

我有一个SwiftUI表单,其中包含一个选择器、一个文本字段和一个文本:

结构ContentView:View{ var body:一些观点{ 形式{ 部分{ Pickerselection:$selection,label:label{ //填充选择器的代码 }.PickerStyle分段PickerStyle HStack{ text字段标题,text:$text 文本 } } } } } 上述代码将生成以下UI:

我能够轻松地在选择器中选择第二项,如下所示:

在下面,您可以看到我可以通过点击文本字段启动文本输入:

为了在更新选择器值时关闭键盘,添加了一个绑定,可以在以下代码块中看到:

Pickerselection:Bindingget:{ //获取所选段的代码 },设置:{中的索引 //设置所选段的代码 自恋 },label:label{ //填充选择器的代码 } 通过以下方法提供对self.endEditing的调用:

功能编辑{ sendActionselectorUIResponder.resignFirstResponder,收件人:nil,发件人:nil,收件人:nil } 下面的屏幕截图显示,选择选择器的不同部分将取消键盘:

到目前为止,一切正常。但是,我想在点击文本字段之外的任何位置时关闭键盘,因为我无法确定在拖动表单的包含滚动视图时如何关闭键盘

我试图添加以下实现,以在点击表单时关闭键盘:

形式{ 部分{ //采摘者 HStack{ //文本字段 //正文 } } }.ontapsigne{ 自恋 } 下面的两个屏幕截图显示TextField能够成为第一响应者并显示键盘。点击文本字段外时,键盘将成功关闭:

但是,在尝试选择“选择器”的不同段时,键盘不会关闭。事实上,我无法选择不同的段,即使在键盘被关闭之后。我假定无法选择其他段,因为附加到表单的点击手势阻止了选择

以下屏幕截图显示了在显示键盘并执行轻触手势时尝试在选择器中选择第二个值的结果:


当点击文本字段外部时,我可以做什么来允许选择选择器的段,同时允许关闭键盘?

您可以将所有代码放在VStack{code}中,向其中添加间隔符,并将onTap添加到此VStack中。这将允许您通过单击屏幕上的任意位置来关闭键盘

见下面的代码:

import SwiftUI

struct ContentView: View {

        @State private var text: String = "Test"

        var body: some View {
            VStack {
                HStack {
                    TextField("Hello World", text: $text)
                    Spacer()
                }
                Spacer()
            }
            .background(Color.red)
            .onTapGesture {
                self.endEditing()
            }
        }

        func endEditing() {
            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        }
    }
将HStack或VStack的背景色更改为红色可以简化计算用户可以单击以关闭的位置

复制并粘贴准备运行示例的代码

import SwiftUI

struct ContentView: View {
    @State private var tipPercentage = 2
    let tipPercentages = [10, 15, 20, 25, 0]
    @State var text = ""

    @State var isEdited = false
    var body: some View {
        Form {
            Section {
                Picker("Tip percentage", selection: $tipPercentage) {
                    ForEach(0 ..< tipPercentages.count) {
                        Text("\(self.tipPercentages[$0])%")
                    }
                }
                .pickerStyle(SegmentedPickerStyle())
                HStack {
                    TextField("Amount", text: $text, onEditingChanged: { isEdited in
                        self.isEdited = isEdited
                    }).keyboardType(.numberPad)
                }
            }
        }.gesture(TapGesture().onEnded({
            UIApplication.shared.windows.first{$0.isKeyWindow }?.endEditing(true)
        }), including: isEdited ? .all : .none)
    }

}
仅当文本字段IsEditd==true时,才启用表单的点击手势以通过点击任意位置完成编辑


一旦ISEDIT==false,您的选择器将像以前一样工作。

不幸的是,此解决方案的结果与我的解决方案的结果相同。这是因为您的.ontapsignature附加到了表单{code}。尝试使用带有间隔符的VStack{}和HStack{}将HStack{TextField Text}和红色下方的空白区域着色。当前,您的整个视图为红色。