SwiftUI:ScrollView 的顶部和底部可以有不同的背景颜色吗?

lla*_*ish 4 background scrollview swift swiftui

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

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

在此输入图像描述

use*_*ser 12

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

.background(VStack(spacing: .zero) { Color.blue; Color.red })
Run Code Online (Sandbox Code Playgroud)


小智 6

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

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

演示