gpt4 book ai didi

ios - @Environment dismiss 的存在导致列表在滚动时不断重建其内容

转载 作者:行者123 更新时间:2023-12-05 04:26:52 28 4
gpt4 key购买 nike

我需要构建一个 TextFields 列表,其中每个字段都与焦点 ID 相关联,以便我可以在接收到焦点时自动滚动到这样的文本字段。实际上,真正的应用程序要复杂一些,其中还包括 TextEditors 和许多其他控件。

现在,我发现如果我的 View 定义了 @Environment(\.dismiss) private var dismiss,那么在手动滚动期间列表一直在重建。如果我只是注释掉 @Environment(\.dismiss) private var dismiss 行,那么在我滚动时不会重建列表。显然,我希望能够在用户单击某个按钮时关闭我的 View 。在真正的应用程序中,情况更糟:在滚动过程中一切都滞后,我无法平滑滚动。我的 list 并不大,只有 10 件左右。

这是一个演示示例:

struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink {
DismissListView()
} label: {
Text("Go to see the list")
}
}
}
}

struct DismissListView: View {
@Environment(\.dismiss) private var dismiss

enum Field: Hashable {
case line(Int)
}

@FocusState private var focus: Field?
@State private var text: String = ""

var body: some View {
ScrollViewReader { proxy in
List {
let _ = print("body is rebuilding")

Button("Dismiss me") {
dismiss()
}

Section("Section") {
ForEach((1...100), id: \.self) {num in
TextField("text", text: $text)
.id(Field.line(num))
.focused($focus, equals: .line(num))
}
}
}
.listStyle(.insetGrouped)
.onChange(of: focus) {_ in
withAnimation {
proxy.scrollTo(focus, anchor: .center)
}
}
}
}
}

问题是:

  • 为什么在定义了 @Environment(\.dismiss) private var dismiss 时手动来回滚动列表,而在未定义 dismiss 时不会发生同样的情况?
  • 是否有任何解决方法:我需要能够在焦点更改时使用 ScrollProxyReader 来聚焦任何文本字段,并且我需要能够关闭 View ,但同时我需要避免不断重建滚动过程中的列表,因为它会降低应用程序性能并且滚动变得参差不齐...

附言当定义了 dismiss 并滚动列表时,演示应用程序不断输出“body is rebuilding”,但如果任何文本字段手动获得焦点,则即使仍然定义了 dismiss,也不会再打印“body is rebuilding”。

最佳答案

  1. 我可以做出一个假设,但这实际上只是一个猜测(基于经验、观察等)。事实上,所有 WHY 都应该在 https://developer.apple.com/forums/ 上询问,例如“为什么会发生这个 sh...(bug)” (那里有苹果的工程师)或者举报给https://developer.apple.com/bug-reporting/

  2. 一个解决方案是将 dismiss 依赖部分分离到专用 View 中,以便将其从父主体中隐藏(因此不影响它)

    struct DismissView: View {
// visible only for this view !!
@Environment(\.dismiss) private var dismiss

var body: some View {
Button("Dismiss me") {
// affects current context, so it does not matter
// in which sub-view is called
dismiss()
}
}
}

var body: some View {
ScrollViewReader { proxy in
List {
let _ = print("body is rebuilding")
DismissView() // << here !!

// ... other code

关于ios - @Environment dismiss 的存在导致列表在滚动时不断重建其内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72919861/

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