繁体   English   中英

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

[英]How to Hide Keyboard in SwiftUI Form Containing Picker?

我有一个SwiftUI Form ,其中包含一个Picker 、一个TextField和一个Text

struct ContentView: View {

    var body: some View {
        Form {
            Section {
                Picker(selection: $selection, label: label) {
                    // Code to populate picker
                }.pickerStyle(SegmentedPickerStyle())
                HStack {
                    TextField(title, text: $text)
                    Text(text)
                }
            }
        }
    }

}

上面的代码会产生以下 UI:

显示选择器和带有标签的文本字段的 iOS 应用程序的屏幕截图

我可以轻松地 select 选择器中的第二项,如下图所示:

iOS 应用程序的屏幕截图,在选择器中显示更新的选择

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

在文本字段中显示用于文本输入的键盘的 iOS 应用程序的屏幕截图

为了在Picker值更新时关闭键盘,添加了一个Binding ,可以在以下代码块中看到:

Picker(selection: Binding(get: {
        // Code to get selected segment
    }, set: { (index) in
        // Code to set selected segment
        self.endEditing()
    }), label: label) {
        // Code to populate picker
    }

以下方法提供了对self.endEditing()的调用:

func endEditing() {
    sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}

以下屏幕截图显示选择Picker的不同部分会关闭键盘:

iOS 应用程序的屏幕截图,在选择新的选择器段时显示已关闭的键盘

到目前为止,一切都按预期工作。 但是,我想在点击TextField之外的任何位置时关闭键盘,因为在拖动Form的包含滚动视图时我无法弄清楚如何关闭键盘。

我尝试添加以下实现以在点击Form时关闭键盘:

Form {
    Section {
        // Picker
        HStack {
            // TextField
            // Text
        }
    }
}.onTapGesture {
    self.endEditing()
}

下面,以下两个屏幕截图显示TextField能够成为第一响应者并显示键盘。 然后在TextField之外点击时成功关闭键盘:

在点击文本字段后显示显示键盘的 iOS 应用程序的屏幕截图

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

以下屏幕截图显示了在显示键盘并实现轻击手势时尝试 select Picker中的第二个值的结果:

显示显示的键盘和先前选择的选择器段的 iOS 应用程序的屏幕截图

我可以做些什么来允许选择Picker的段,同时允许在TextField之外点击时关闭键盘?

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

}

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

一旦isEdited == false ,您的选择器就会像以前一样工作。

您可以将所有代码放在 VStack{ code } 中,向其中添加 Spacer() 并将 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 的背景颜色更改为红色可以简化确定用户可以单击以关闭的位置。

复制并粘贴代码以获得准备运行的示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM