SwiftUI:通过 View.scrollPosition(id:anchor:) 观察滚动位置会中断滚动

问题描述 投票:0回答:1

我正在尝试使用新的(在 WWDC 2023 上宣布并在 iOS 17 和 macOS 14 中可用)API 来观察 SwiftUI 的滚动位置

ScrollView

我有以下视图,但我无法使其正常工作。也就是说,使用

scrollPosition(id:anchor)
视图修饰符会使滚动视图变得疯狂。在某些时候,在某些情况下,即使在最紧急的时候,滚动视图也会开始跳跃,并且在尝试滚动时出现卡顿。请参阅此处的屏幕录制:https://twitter.com/krajaac/status/1714191037927764149

代码:

ScrollView(.vertical) {
                LazyVGrid(
                    columns: [.init(.adaptive(minimum: self.itemSize.width), spacing: Constants.columnSpacing, alignment: .center)],
                    alignment: .center,
                    spacing: Constants.sectionSpacing
                ) {
                    ForEach(self.sectionData) { section in
                        Section(section.title) {
                            ForEach(section.items) { item in
                                Text(item.text)
                                    .frame(width: self.itemSize.width, height: self.itemSize.height)
                            }
                        }
                    }
                }
                .scrollTargetLayout()
            }
            .scrollPosition(id: self.$currentItemID) // TODO: Comment out this line to make the scrolling work

整个代码可以在我的 GitHub 存储库中找到:https://github.com/tomaskraina/feedbackassistant.apple.com/blob/master/ScrollPositionVsLazyVGrid/ScrollPositionVsLazyVGrid/ContentView.swift

我做错了什么还是这是 SwiftUI 中的错误?

ios macos swiftui scrollview wwdc
1个回答
0
投票

我仍然没有弄清楚这个问题的根本原因,但是在自定义

ScrollView
中“隐藏”
LazyVGrid
--
View
的内容,这样可以修复由于某种原因导致的滚动问题:

struct ContentView: View {

    private var itemSize: CGSize = .init(width: 50.0, height: 50.0)

    // Annotated as @State to create the sections only once
    @State private var sectionData: [SectionInfo] = makeSections()

    // Tracking scroll position
    @State private var currentItemID: MyIdentifier?
    var currentItemDescription: String { self.currentItemID?.stringId ?? "nil" }

    var body: some View {
        VStack {
            // 1. Scroll View
            ScrollView(.vertical) {
                // ContentGrid is just a custom view with LazyVGrid underneath
                ContentGrid(itemSize: self.itemSize, sectionData: self.sectionData)
                .scrollTargetLayout()
            }
            .scrollPosition(id: self.$currentItemID)

            Divider()

            // 2. Footer
            Group {
                Label(
                    title: { Text(self.currentItemDescription) },
                    icon: { Image(systemName: "42.circle") }
                )
            }
            .padding()
        }
        #if os(macOS)
        .frame(width: 320, height: 480, alignment: .center)
        #endif
    }
}

// MARK: - Private

struct ContentGrid: View {

    var itemSize: CGSize
    var sectionData: [SectionInfo]

    var body: some View {
        LazyVGrid(
            columns: [.init(.adaptive(minimum: self.itemSize.width), spacing: Constants.columnSpacing, alignment: .center)],
            alignment: .center,
            spacing: Constants.sectionSpacing
        ) {
            ForEach(self.sectionData) { section in
                Section(section.title) {
                    ForEach(section.items) { item in
                        Text(item.text)
                            .frame(width: self.itemSize.width, height: self.itemSize.height)
                    }
                }
            }
        }
    }
}

在此处查看屏幕录制:https://mastodon.social/@tomkraina/111251021544613267

© www.soinside.com 2019 - 2024. All rights reserved.