gpt4 book ai didi

swiftui - 如果 onPreferenceChange 在 SwiftUI 中的 ScrollView 内,为什么不调用它?

转载 作者:行者123 更新时间:2023-12-04 11:10:17 26 4
gpt4 key购买 nike

我一直在使用 ScrollView 看到首选项键的一些奇怪行为。如果我把 onPreferenceChangeScrollView它不会被调用,但如果我把它放在外面它会!

我已经设置了一个宽度首选项键,如下所示:

struct WidthPreferenceKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue = CGFloat(0)

static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}

以下简单 View 不会打印:

struct ContentView: View {
var body: some View {
ScrollView {
Text("Hello")
.preference(key: WidthPreferenceKey.self, value: 20)
.onPreferenceChange(WidthPreferenceKey.self) {
print($0) // Not being called, we're in a scroll view.
}
}
}
}

但这有效:

struct ContentView: View {
var body: some View {
ScrollView {
Text("Hello")
.preference(key: WidthPreferenceKey.self, value: 20)
}
.onPreferenceChange(WidthPreferenceKey.self) {
print($0)
}
}
}

我知道我可以使用后一种方法来解决这个问题,但有时我在一个无法访问其父 ScrollView 的 subview 中,但我仍然想记录一个首选项键。

关于如何获得的任何想法 onPreferenceChangeScrollView 内被调用?

Note: I get Bound preference WidthPreferenceKey tried to update multiple times per frame. when I put the function inside the scroll view, which might explain what is going on but I can't figure it out.



谢谢!

最佳答案

我一直试图找出这个问题很长一段时间并找到了如何处理它,尽管我使用的方式只是一种解决方法。

Use onAppear to ScrollView with a flag to make its children show up.

...
@State var isShowingContent = false
...

ScrollView {
if isShowingContent {
ContentView()
}
}
.onAppear {
self.isShowingContent = true
}
或者,
使用 List而不是它。
它具有滚动功能,您可以在 UI 方面使用自己的功能和 UITableView 外观对其进行自定义。最重要的是它按我们的预期工作。
【如果你有时间阅读更多】
说说我对这个问题的看法。
我已经确认 onPreferenceChange未在 处调用 bootstrap View 放入 ScrollView 的时间.我不确定这是否是正确的行为。但是,我认为这是错误的,因为 ScrollView必须能够包含任何 View ,即使其中一些 View 使用 PreferenceKey 在其中的 View 之间传递任何数据。如果这是正确的行为,我们在创建自定义 View 时很容易遇到麻烦。
让我们更详细地了解一下。
我想 ScrollView在引导时设置其 subview 时,它的工作方式与其他容器 View (例如 List、(H/V)Stack)略有不同。换句话说, ScrollView会尝试以自己的方式绘制(或布置) child 。不幸的是,这种方式会影响 child 的布局机制,正如我们所看到的那样不正确地工作。我们可以猜测调试 View 中的以下消息发生了什么。

TestHPreferenceKey tried to update multiple times per frame.


或许是一个证据,告诉我们 child 的更新发生在 ScrollView的同时。正在为其设置做一些事情。此时,可以猜测到 PreferenceKey 的更新已被忽略。
这就是为什么我试图将放置 subview 放到 onAppear .
我希望这对那些在 SwiftUI 上遇到各种问题的人有用。

关于swiftui - 如果 onPreferenceChange 在 SwiftUI 中的 ScrollView 内,为什么不调用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58720495/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com