当SwiftUI TextEditor在子视图中工作时,我遇到了麻烦。
这是一个小例子,为我演示了这个问题:
import SwiftUI
struct ContentView: View {
@State private var someText: String = "Hello World"
var body: some View {
VStack {
HStack {
Button("Text 1", action: {someText = "hello"})
Button("Text 2", action: {someText = "world"})
}
ViewWithEditor(entry: $someText)
}
}
}
struct ViewWithEditor: View {
@Binding var entry: String
@State private var localString: String
var body: some View
{
VStack {
TextEditor(text: $localString)
}
}
init(entry: Binding<String>) {
self._entry = entry
self._localString = State(initialValue: entry.wrappedValue)
print("init set local String to: (localString)")
}
}
当我单击按钮时,我希望编辑器文本改变,但是它仍然保持其初始值。
print语句显示"localString"变量正在更新
是TextEditor坏了还是我错过了一些基本的东西??
如果你将按钮移动到与TextEditor相同的视图中,直接更改本地状态变量,它会像预期的那样工作。
这是在MacOS下运行的,以防有什么不同。
TIA艾伦。
好的。因此,代理绑定为我完成了这项工作。参见下面更新的编辑器视图:
struct ViewWithEditor: View {
@Binding var entry: String
var body: some View
{
let localString = Binding<String> (
get: {
entry
},
set: {
entry = $0
}
)
return VStack {
Text(entry)
TextEditor(text: localString)
}
}
有点难看(代理绑定看起来很混乱),但在某些方面更简单…
它允许在将编辑结果推入绑定变量之前对其进行审查/拒绝。
这是因为绑定条目var在初始化ViewWithEditor后实际上没有被使用。为了在不使用代理绑定的情况下使其工作,将onChange添加到ViewWithEditor中,如下所示:
struct ViewWithEditor: View {
@Binding var entry: String
@State private var localString: String
var body: some View
{
VStack {
TextEditor(text: $localString)
}
.onChange(of: entry) {
localString = $0
}
}
init(entry: Binding<String>) {
self._entry = entry
self._localString = State(initialValue: entry.wrappedValue)
print("init set local String to: (localString)")
}
}
这里的问题是,如果localString改变,现在条目不会更新。您可以使用与之前相同的方法:
var body: some View
{
VStack {
TextEditor(text: $localString)
}
.onChange(of: entry) {
localString = $0
}
.onChange(of: localString) {
entry = $0
}
}
,但为什么不只是使用$entry作为textteditor的绑定字符串?