当
TextField
这样创建时
TextField(
"Describe...",
text: $text,
axis: .vertical
)
.focused(focused, equals: .prompt)
.textFieldStyle(.roundedBorder)
.lineLimit(2...)
.modifier(ClearButton(text: $text))
.submitLabel(.done)
.onSubmit { hideKeyboard()
print("test")
}
当按下键盘完成按钮时,它会创建一个新行。我根本不想在
TextField
中添加任何新行。
.submitLabel
应该可以做到。所以我添加了,但没有。
.onSubmit
回调,但这也不起作用。事实上,“test”永远不会被打印出来。
不是因为textField的多行,而是因为轴的原因。如果您删除行限制,问题仍然存在,但如果您更改轴,文本字段现在“有效”(它不是多行)。如果您使用
TextEditor
,也会发生同样的情况。但是,如果您想要一个能够关闭键盘的多行文本字段,则用户友好的解决方案可以是添加工具栏。现在,用户将把文本字段解释为多行文本字段(因为返回按钮),并且可以选择禁用文本字段。
struct TestView: View {
enum Field {
case prompt
}
@FocusState var focus: Field?
@State var text = ""
var body: some View {
VStack {
TextField(
"Describe...",
text: $text,
axis: .vertical
)
.focused($focus, equals: .prompt)
.textFieldStyle(.roundedBorder)
.lineLimit(2...)
.submitLabel(.return) // <- change to return
.toolbar { // adding the toolbar
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button("Done") {
focus = nil
}
}
}
}
}
}
我写了一篇短文,介绍如何使用
FocusState
和 onChange
来模拟多行中的返回键按下 TextField
或 TextEditor
:
struct MyView: View {
@State
var text = ""
@FocusState
var isFocused: Bool
var body: some View {
TextField("Enter text", text: $text, axis: .vertical)
.submitLabel(.done)
.focused($isFocused)
.onChange(of: text) { newValue in
guard isFocused else { return }
guard newValue.contains("\n") else { return }
isFocused = false
text = newValue.replacing("\n", with: "")
}
}
}
您可以将这些修饰符提取到自定义
ViewModifier
中,以便于重用它:
struct MultilineSubmitViewModifier: ViewModifier {
init(
text: Binding<String>,
submitLabel: SubmitLabel,
onSubmit: @escaping () -> Void
) {
self._text = text
self.submitLabel = submitLabel
self.onSubmit = onSubmit
}
@Binding
private var text: String
private let submitLabel: SubmitLabel
private let onSubmit: () -> Void
@FocusState
private var isFocused: Bool
func body(content: Content) -> some View {
content
.focused($isFocused)
.submitLabel(submitLabel)
.onChange(of: text) { newValue in
guard isFocused else { return }
guard newValue.contains("\n") else { return }
isFocused = false
text = newValue.replacingOccurrences(of: "\n", with: "")
onSubmit()
}
}
}
您还可以创建自定义视图扩展以使其更易于使用:
public extension View {
func onMultilineSubmit(
in text: Binding<String>,
submitLabel: SubmitLabel = .done,
action: @escaping () -> Void
) -> some View {
self.modifier(
MultilineSubmitViewModifier(
text: text,
submitLabel: submitLabel,
onSubmit: action
)
)
}
}