如何在以相机为父SwiftUI的滚动视图顶部应用不透明度

时间:2020-11-11 17:45:47

标签: swiftui

我在相机视图中有一个滚动视图,我需要在滚动视图的顶部应用不透明度

实际/预期行为

enter image description here enter image description here

我已经尝试过了,但没有成功。

var body: some View {
    ZStack(alignment: .top) {
        VStack {
            
        }
        .frame(
            minWidth: 0,
            maxWidth: .infinity,
            minHeight: 0,
            maxHeight: 10
        )
        .opacity(0.5)
        
        ScrollView(.vertical, showsIndicators: false) {
            ScrollViewReader { scrollView in
                VStack(alignment: .leading, spacing: 16) {
                    ForEach(messages) { message in
                        LazyVStack(alignment: .leading, spacing: 4) {
                            Text("\(message.sender)")
                                .kerning(0.02)
                                .fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/)
                                .font(.system(size: 13))
                                .lineSpacing(21)
                                .foregroundColor(Color.white)
                            Text("\(message.text)")
                                .kerning(0.02)
                                .fontWeight(.medium)
                                .font(.system(size: 13))
                                .lineSpacing(21)
                                .foregroundColor(Color.white)
                        }
                    }
                }
                .onChange(of: messages) { _ in
                    scrollView.scrollTo(messages.count + 1, anchor: .bottom)
                }
                .onAppear {
                    scrollView.scrollTo(messages.count, anchor: .bottom)
                }
            }
        }
    }
}

如何在此滚动视图的顶部应用不透明度?

1 个答案:

答案 0 :(得分:0)

我用以下代码解决了这个问题

func getNameOpacity(_ distance: CGFloat) -> Double {
    return distance < 3 ? 1 : distance < 5 ? 0.7 : distance < 7 ? 0.5 : distance < 9 ? 0.3 : 0
}

func getTextOpacity(_ distance: CGFloat) -> Double {
    return distance < 23 ? 1 : distance < 25 ? 0.7 : distance < 27 ? 0.5 : distance < 29 ? 0.3 : 0
}

var body: some View {
    GeometryReader { outsideProxy in
        ScrollView(.vertical, showsIndicators: false) {
            ScrollViewReader { scrollView in
                VStack(alignment: .leading, spacing: 16) {
                    ForEach(messages) { message in
                        GeometryReader { insideProxy in
                            let distanceFromTop = outsideProxy.frame(in: .global).minY - insideProxy.frame(in: .global).minY + 6
                            let nameOpacity = getNameOpacity(distanceFromTop)
                            let textOpacity = getTextOpacity(distanceFromTop)
                            
                            VStack(alignment: .leading, spacing: 4) {
                                Text("\(message.sender)")
                                    .kerning(0.02)
                                    .fontWeight(.bold)
                                    .font(.system(size: 13))
                                    .lineSpacing(21)
                                    .foregroundColor(Color.white)
                                    .opacity(nameOpacity)
                                Text("\(message.text)")
                                    .kerning(0.02)
                                    .fontWeight(.medium)
                                    .font(.system(size: 13))
                                    .lineSpacing(21)
                                    .foregroundColor(Color.white)
                                    .opacity(textOpacity)
                            }
                        }
                    }
                    .frame(width: 100, height: 35, alignment: .center)
                }
                .onChange(of: messages) { _ in
                    scrollView.scrollTo(messages.count + 1, anchor: .bottom)
                }
                .onAppear {
                    scrollView.scrollTo(messages.count, anchor: .bottom)
                }
            }
        }
    }
}