1

我有一个SwiftUI Form包含 a Picker、 aTextField和 a 的 a 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 应用程序的屏幕截图

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

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 应用程序的屏幕截图

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

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

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

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

4

2 回答 2

1
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,您的选择器将像以前一样工作。

于 2020-01-09T16:15:56.067 回答
0

您可以将所有代码放在 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 的背景颜色更改为红色可以简化确定用户可以单击以关闭的位置。

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

于 2019-10-22T23:16:38.843 回答