最小可复制示例:
在SceneDelegate.swift
中:
let contentView = Container()
在ContentView.swift
中:
struct SwiftUIView: View {
@State var text: String = ""
var body: some View {
VStack {
CustomTextFieldView(text: $text)
}
}
}
struct Container: View {
@State var bool: Bool = false
@State var text: String = ""
var body: some View {
Button(action: {
self.bool.toggle()
}) {
Text("Sheet!")
}
.sheet(isPresented: $bool) {
SwiftUIView()
}
}
}
在CustomTextField.swift
中:
struct CustomTextFieldView: View {
@Binding var text: String
@State var editing: Bool = false
var body: some View {
Group {
if self.editing {
textField
.background(Color.red)
} else {
ZStack(alignment: .leading) {
textField
.background(Color.green)
Text("Placeholder")
}
}
}
.onTapGesture {
withAnimation {
self.editing = true
}
}
}
var textField: some View {
TextField("", text: $text)
}
问题:
运行上面的代码并突出显示文本字段后,应用程序崩溃。我注意到了一些事情:
withAnimation
代码或ZStack
文件中的CustomTextField
,则该应用不会崩溃,但是TextField失去了焦点。VStack
中的SwiftUIView
,则应用不会崩溃,但TextField会失去焦点。问题:
答案 0 :(得分:1)
您有两个。 两个不同的TextField不能同时处于编辑状态。
唯一可行的方法是Asperi建议。
代码崩溃的原因并不容易解释,但是在当前的SwiftUI中是可以预期的。
您必须了解,组不是标准容器,就像一个“块”,您可以在其上应用一些修饰符。在ViewBuilder中删除组并使用包装体
struct CustomTextFieldView: View {
@Binding var text: String
@State var editing: Bool = false
@ViewBuilder
var body: some View {
if self.editing {
TextField("", text: $text)
.background(Color.red)
.onTapGesture {
self.editing.toggle()
}
} else {
ZStack(alignment: .leading) {
TextField("", text: $text)
.background(Color.green)
.onTapGesture {
self.editing.toggle()
}
}
}
}
}
代码将停止崩溃,但是还有其他问题,键盘将立即关闭。那是由于应用了点击手势。
所以,信不信由你,您只能使用一个TextField。
struct CustomTextFieldView: View {
@Binding var text: String
@State var editing = false
var textField: some View {
TextField("", text: $text, onEditingChanged: { edit in
self.editing = edit
})
}
var body: some View {
textField.background(editing ? Color.green : Color.red)
}
}
根据需要在代码的其他位置使用此自定义文本字段
答案 1 :(得分:0)
为CustomTextFieldView
(针对Xcode 11.2 / iOS 13.2经过测试并可以使用)尝试以下操作
struct CustomTextFieldView: View {
@Binding var text: String
@State var editing: Bool = false
var body: some View {
TextField("", text: $text)
.background(self.editing ? Color.red : Color.green)
.onTapGesture {
withAnimation {
self.editing = true
}
}
}
}
由于状态变化重新计算正文后,如何保持TextField的焦点?
您不会失去焦点,只需删除整个文本字段即可,因此解决方案不是替换文本字段,而是修改其属性(即背景)。可以将其放入ZStack中,但请保留其中一个。