SwiftUI显示不会在更改状态的子链接上更新

时间:2020-05-16 02:11:58

标签: swift swiftui

Swift 5.2

我有以下代码。 (它是从更加复杂的多页面UI中提炼出来的。)核心点是有些NavigationLink的文本反映了它们的内容,当您单击它们时,您可以更改其内容。 (我意识到在这个简化的示例中,enabled是类级的,而不是特定于链接的。这是一种简化。它仍然说明了我的问题。)现在,我期望发生的事情是当我单击进入链接(“已禁用”),单击切换,然后保留导航链接,该项目现在应显示为“已启用”。它没有,但是仍然说“ disabled”。考虑用户界面:

struct ContentView: View {
    @State var enabled: Bool = false
    @State var items: [String] = ["item"]

    var body: some View {
        NavigationView {
            Section {
                uiPrint("CV main")
                ForEach(self.items.indices) { idx in
                    uiPrint("CV item \(idx)")
                    NavigationLink(destination: Toggle(isOn: self.$enabled){Text("enable")}) {
                        uiPrint("CV link \(idx)")
                        if self.enabled {
                            Text("enabled")
                        } else {
                            Text("disabled")
                        }
                    }
                }
            }
        }
    }
}

public func uiPrint(_ str: String) -> AnyView? {
    print(str)
    return Optional<AnyView>.none
}

运行此命令时,会收到日志(用括号括起来的自己的操作):

CV main
CV item 0
CV link 0
[CLICK LINK]
[CLICK TOGGLE]
2020-05-15 21:38:29.726757-0400 Test[39097:798734] invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
CV main
[CLICK BACK]

,该链接仍显示为“已禁用”。请注意,日志表明在切换时重新渲染主视图时,ForEach不是。

这是为什么,当内容更改(由内容本身更改)时,如何使主视图完全更新?

我怀疑它与警告有关-打破建议的符号会产生以下堆栈跟踪:

#0  0x0000000182b4d47c in _CFRunLoopError_RunCalledWithInvalidMode ()
#1  0x00000001035cf18c in _dispatch_client_callout ()
#2  0x00000001035d0bd8 in _dispatch_once_callout ()
#3  0x0000000182b4d6c4 in CFRunLoopRunSpecific ()
#4  0x0000000186741858 in __88-[UISwitchModernVisualElement _handleLongPressWithGestureLocationInBounds:gestureState:]_block_invoke ()
#5  0x0000000186d2bc10 in _runAfterCACommitDeferredBlocks ()
#6  0x0000000186d1b13c in _cleanUpAfterCAFlushAndRunDeferredBlocks ()
#7  0x0000000186d4c88c in _afterCACommitHandler ()
#8  0x0000000182b52c54 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#9  0x0000000182b4d8e4 in __CFRunLoopDoObservers ()
#10 0x0000000182b4dd84 in __CFRunLoopRun ()
#11 0x0000000182b4d660 in CFRunLoopRunSpecific ()
#12 0x000000018cf5e604 in GSEventRunModal ()
#13 0x0000000186d2215c in UIApplicationMain ()
#14 0x000000010290982c in main at REDACTED/AppDelegate.swift:13
#15 0x00000001829c91ec in start ()

除了牵连UISwitchModernVisualElement(可能是切换键)之外,似乎并没有太大帮助。

答案https://stackoverflow.com/a/59019554/513038表示这是因为视图是打开的,并且在状态发生变化时被锁定(?)或类似的东西,但是建议的解决方案(使反映变化的东西不属于触发事物链的一部分)我认为此更改似乎并不适用),因为每个列表项都需要自己显示状态,以及指向更改状态的链接,并且当更改发生时,列表甚至都不会重新布局出来如何使它表现出预期的效果?

1 个答案:

答案 0 :(得分:0)

看来您的uiPrint函数会导致这种现象。我可以重现该示例,当您在创建视图时不创建这些其他“无”视图以打印值时,该示例就可以工作。

工作示例项目:https://github.com/ralfebert/SwiftUIPlayground/blob/master/SwiftUIPlayground/Views/LinkedStateChangeView.swift

我不确定为什么其他“无”视图会干扰国家行为。

还可以与ForEach(self.items.indicies)ForEach(self.items, id: \.self)一起使用。

相关问题