SwiftUI:如何根据滚动视图的用户当前滚动位置同步/更改进度条进度?

Posted

技术标签:

【中文标题】SwiftUI:如何根据滚动视图的用户当前滚动位置同步/更改进度条进度?【英文标题】:SwiftUI: How do I sync/change progress bar progress based on scrollview’s user current scroll position? 【发布时间】:2021-02-18 22:19:56 【问题描述】:

我在 ScrollView 中有水平进度条,我需要在用户滚动时更改该进度条值。

有没有办法将一些值绑定到当前滚动位置?

【问题讨论】:

这能回答你的问题吗? SwiftUI | Get current scroll position from ScrollView 【参考方案1】:

您可以通过几个GeometryReaders 来做到这一点。

我的方法:

    获取ScrollView容器的总高度 获取内容的内部高度 找出总可滚动高度的差异 获取滚动视图容器顶部和内容顶部之间的距离 将顶部之间的距离除以可滚动的总高度 使用PreferenceKeys 设置proportion @State

代码:

struct ContentView: View 
    @State private var scrollViewHeight: CGFloat = 0
    @State private var proportion: CGFloat = 0

    var body: some View 
        VStack 
            ScrollView 
                VStack 
                    ForEach(0 ..< 100)  index in
                        Text("Item: \(index + 1)")
                    
                
                .frame(maxWidth: .infinity)
                .background(
                    GeometryReader  geo in
                        let scrollLength = geo.size.height - scrollViewHeight
                        let rawProportion = -geo.frame(in: .named("scroll")).minY / scrollLength
                        let proportion = min(max(rawProportion, 0), 1)

                        Color.clear
                            .preference(
                                key: ScrollProportion.self,
                                value: proportion
                            )
                            .onPreferenceChange(ScrollProportion.self)  proportion in
                                self.proportion = proportion
                            
                    
                )
            
            .background(
                GeometryReader  geo in
                    Color.clear.onAppear 
                        scrollViewHeight = geo.size.height
                    
                
            )
            .coordinateSpace(name: "scroll")

            ProgressView(value: proportion, total: 1)
                .padding(.horizontal)
        
    

struct ScrollProportion: PreferenceKey 
    static let defaultValue: CGFloat = 0

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

结果:

【讨论】:

以上是关于SwiftUI:如何根据滚动视图的用户当前滚动位置同步/更改进度条进度?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 中的底部优先滚动

如何为视图提供固定位置,使其不受 SwiftUI 中滚动的影响

获取 SwiftUI ScrollView 的当前滚动位置

SwiftUI 滚动/列表滚动事件

SwiftUI ScrollView 滚动到相对位置

SwiftUI URLImage 水平滚动视图