ios SwiftUI:通过View观察滚动位置,scrollPosition(id:锚:)中断滚动

i2loujxw  于 2023-10-21  发布在  iOS
关注(0)|答案(1)|浏览(168)

我尝试使用新的(在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 repo中找到:https://github.com/tomaskraina/feedbackassistant.apple.com/blob/master/ScrollPositionVsLazyVGrid/ScrollPositionVsLazyVGrid/ContentView.swift
是我做错了什么,还是SwiftUI中的bug?

zmeyuzjn

zmeyuzjn1#

我还没有弄清楚这个问题的根本原因,但是在这样的自定义View中“隐藏”ScrollView--LazyVGrid的内容可以修复滚动的问题。

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

相关问题