更改文本字段的禁用状态时出现“AttributeGraph:检测到循环”错误
Get `AttributeGraph: cycle detected` error when changing disabled state of text field
当我在我的视图中更新 isDisabled
状态变量时,它会按预期更新我的文本字段的 .disabled
修饰符,但随后会导致大约 40 个以下错误实例出现在控制台(末尾有不同的属性编号):
=== AttributeGraph: cycle detected through attribute 200472 ===
然后它说:AttributeGraphError[59460:4808136] [SwiftUI] Modifying state during view update, this will cause undefined behavior.
这是产生错误的代码的最小版本:
struct ContentView: View {
@State var isDisabled = false
@State var text = ""
var body: some View {
VStack {
TextField("", text: $text)
.textFieldStyle(.roundedBorder)
.disabled(isDisabled)
Button("Disable text field") { isDisabled = true }
}
}
}
如何修复此错误?
经过几个小时的痛苦调试,我找到了解决方案!
事实证明,问题是您无法在用户仍在编辑文本字段时禁用文本字段。相反,您必须先退出文本字段(即关闭键盘),然后然后禁用文本字段。
这是我更新后的代码:
struct ContentView: View {
@State var isDisabled = false
@State var text = ""
var body: some View {
VStack {
TextField("", text: $text)
.textFieldStyle(.roundedBorder)
.disabled(isDisabled)
Button("Disable text field") {
closeKeyboard()
isDisabled = true
}
}
}
func closeKeyboard() {
UIApplication.shared.sendAction(
#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil
)
}
}
这是一个 iOS 15+ 的解决方案。
struct ContentView: View {
enum Field: Hashable {
case text
}
@FocusState private var focusedField: Field? // available iOS 15+
@State var isDisabled = false
@State var text = ""
var body: some View {
VStack {
TextField("", text: $text)
.focused($focusedField, equals: .text)
.textFieldStyle(.roundedBorder)
.disabled(isDisabled)
Button("Disable text field") {
focusedField = nil
isDisabled = true
}
}
}
}
当我在我的视图中更新 isDisabled
状态变量时,它会按预期更新我的文本字段的 .disabled
修饰符,但随后会导致大约 40 个以下错误实例出现在控制台(末尾有不同的属性编号):
=== AttributeGraph: cycle detected through attribute 200472 ===
然后它说:AttributeGraphError[59460:4808136] [SwiftUI] Modifying state during view update, this will cause undefined behavior.
这是产生错误的代码的最小版本:
struct ContentView: View {
@State var isDisabled = false
@State var text = ""
var body: some View {
VStack {
TextField("", text: $text)
.textFieldStyle(.roundedBorder)
.disabled(isDisabled)
Button("Disable text field") { isDisabled = true }
}
}
}
如何修复此错误?
经过几个小时的痛苦调试,我找到了解决方案!
事实证明,问题是您无法在用户仍在编辑文本字段时禁用文本字段。相反,您必须先退出文本字段(即关闭键盘),然后然后禁用文本字段。
这是我更新后的代码:
struct ContentView: View {
@State var isDisabled = false
@State var text = ""
var body: some View {
VStack {
TextField("", text: $text)
.textFieldStyle(.roundedBorder)
.disabled(isDisabled)
Button("Disable text field") {
closeKeyboard()
isDisabled = true
}
}
}
func closeKeyboard() {
UIApplication.shared.sendAction(
#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil
)
}
}
这是一个 iOS 15+ 的解决方案。
struct ContentView: View {
enum Field: Hashable {
case text
}
@FocusState private var focusedField: Field? // available iOS 15+
@State var isDisabled = false
@State var text = ""
var body: some View {
VStack {
TextField("", text: $text)
.focused($focusedField, equals: .text)
.textFieldStyle(.roundedBorder)
.disabled(isDisabled)
Button("Disable text field") {
focusedField = nil
isDisabled = true
}
}
}
}