【问题标题】:SwiftUI: Can you have a different background color for the top and bottom of a ScrollView?SwiftUI:你可以为 ScrollView 的顶部和底部设置不同的背景颜色吗?
【发布时间】:2022-10-14 23:04:25
【问题描述】:

ScrollView 的顶部和底部是否可以有不同的背景颜色?

例如,当我向上滚动时,我希望 ScrollView 的绿色背景为蓝色,而当我向下滚动时,我希望 ScrollView 的绿色背景为红色:

【问题讨论】:

  • 我不明白你的目标是什么。

标签: swift swiftui background scrollview


【解决方案1】:

是的,用这个替换你的背景:

.background(VStack(spacing: .zero) { Color.blue; Color.red })

【讨论】:

    【解决方案2】:

    以前的答案是可以的,但是当您向下拖动滚动条时,您可能会看到底部颜色,反之亦然。为了创建预期的行为,我根据当前的滚动偏移量动态调整背景视图的大小。

    struct DoubleSidedBackgroundScrollView<Content: View>: View {
    
        private let ContentBuilder: () -> Content
        private let topColor: Color
        private let bottomColor: Color
        
        @State private var offset: CGFloat = .zero
        
        init(topColor: Color, bottomColor: Color, contentBuilder: @escaping () -> Content) {
            self.ContentBuilder = contentBuilder
            self.topColor = topColor
            self.bottomColor = bottomColor
        }
    
        var body: some View {
            ScrollView {
                ZStack {
                    ContentBuilder()
                
                    GeometryReader { proxy in
                        let offset = proxy.frame(in: .named("scroll")).minY
                        Color.clear.preference(key: ScrollViewOffsetPreferenceKey.self, value: offset)
                    }
                }
            }
            .coordinateSpace(name: "scroll")
            .onPreferenceChange(ScrollViewOffsetPreferenceKey.self) { value in
                offset = value
            }
            .background(
                VStack(spacing: 0) {
                    topColor
                        .frame(
                            height: max(offset + (UIScreen.main.bounds.height / 2), 0),
                            alignment: .top)
                    bottomColor
                }
                .ignoresSafeArea()
            )
        }
    }
    
    private struct ScrollViewOffsetPreferenceKey: PreferenceKey {
        static var defaultValue: CGFloat = .zero
    
        static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
            value = nextValue()
        }
    }
    

    demo

    【讨论】:

      猜你喜欢
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2021-07-25
      • 1970-01-01
      相关资源
      最近更新 更多