SwiftUI ScrollView scrollTo 底部建议的 hack

问题描述

所以我有一个非常复杂的 ScrollView,准确地说是一个聊天机器人,它由以下协调动画组成:

  • 用户消息气泡
  • 聊天机器人正在输入气泡
  • 聊天机器人消息气泡
  • 滚动视图中的用户操作按钮

所有的都一一出现,带有动画和轻微的延迟。每次插入后我都需要滚动到底部。我已经能够很好地使用 ID 和 scrollTo(ID) 来实现这一点,但是我从 SwiftUI 的滚动视图中得到了奇怪的行为。它第一次运行得很好,但是在关闭/重新呈现视图后,一些滚动会中断,这非常令人沮丧,因为我知道代码是正确的。

我尝试了以下 hack,但它不起作用,但我不太确定为什么?希望我们可以将其作为一个社区来解决,并将其作为一种快速简便的方法来滚动到底部,而无需计算当前位于底部的 ID,并希望没有在解雇/重新开放时中断的错误行一个观点:

struct ScrollTrackerBottom: View,Identifiable {
    static idString = "BottOM"
    var id = ScrollTrackerBottom.idString

    var body: some View {
        // Thought the empty view was the problem,// but it didn't work with a text view either when I tried
        EmptyView()
    }
}

这是正文代码的最小版本:

@State var history [ChatState] = [ChatState(.first)]

var body: some View {
    ScrollView(.vertical) {
        ScrollViewReader { scrollView
            ForEach(history,id: \.id) { log in
                // Show older logs without animations
                ShowChatBubbles(log)

                // Show most recent log with animations
                ShowAnimatedChatBubbles(log)
                .onAppear {
                    scrollView.scrollTo(ScrollTrackerBottom.idString,anchor: .none)

                    // I kNow scrolling to log.id is the correct way,but it breaks after the modal is dismissed and reopened
                }
            }

            // Show history.last buttons if it is "their turn" to be animated in
            ShowButtons()
            .onAppear {
                    scrollView.scrollTo(ScrollTrackerBottom.idString,anchor: .none)
            }

            // Add my empty bottom view to hopefully be able to scrollTo it easily
            ScrollTrackerBottom()
        }
    }
}

有谁知道为什么这不起作用?毫无疑问,我知道ID是什么。 ScrollTrackerBottom 是否需要在 ForEach 或类似的东西中才能工作?这值得追求吗?有一个简单的、干净的编码方式来滚动到底部肯定会很好。我真的只是在追这个,因为 Apple 规定的方式似乎有问题,并且在我的模态被解雇并再次呈现后表现不同。需要注意的是,正文代码只是一个大纲,用于上下文,根本不准确,所以不要太看它的实现。

感谢您对此的任何帮助或评论

更新

好的,所以我在上面部分回答了我自己的问题。 ScrollTracker 在以下情况下工作:

  1. 它不包含 EmptyView
  2. 它是通过 ForEach(item,id) 方法添加到滚动视图中的

但我仍然遇到这样的错误,即在解雇/重新演示后,我的 scrollTo 有时会中断。有谁知道为什么?现在有点让我发疯。

无论如何,这是实际工作的跟踪器代码!很快就完成了,所以请随时提出更好/更优化的版本!

struct ScrollTrackerBottom: View,Identifiable {
    static idString = "BottOM"
    var id = ScrollTrackerBottom.idString

    var body: some View {
        Text("")
            .frame(maxHeight: 1) // to limit amount of added space,though I'd rather it be empty
    }
}
@State var history [ChatState] = [ChatState(.first)]
@State var bottomTracker = [ScrollTrackerBottom()]

var body: some View {
    ScrollView(.vertical) {
        ScrollViewReader { scrollView
            ForEach(history,id: \.id) { log in
                ShowChatBubbles(log)
                ShowAnimatedChatBubbles(log)
                .onAppear {
                    scrollView.scrollTo(bottomTracker.first!.id,anchor: .none)
                }
            }

            ShowButtons()
            .onAppear {
                    scrollView.scrollTo(bottomTracker.first!.id,anchor: .none)
            }

            // IMPORTANT PART
            ForEach(bottomTracker,id: \.id) { tracker in
                tracker
            }
        }
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...