SwiftUI - 根据滚动视图的位置更改视图的不透明度

3

我想请问一个关于技术可行性的问题。

我目前有一个浮动的自定义导航栏,它位于自己的父容器中,并具有白色背景和0%的不透明度。当滚动视图在hero image后滚动时,我想将该父容器的不透明度从0%更改为50%。

var body: some View {
    ZStack {
        ScrollView(.vertical, showsIndicators: false) {
            GeometryReader { geometry in
                ZStack{
                    if geometry.frame(in: .global).minY <= 0 {
                        Image(self.venueImage)
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: geometry.size.width, height: geometry.size.height)
                        .offset(y: geometry.frame(in: .global).minY/9)
                        .clipped()
                    } else {
                        Image(self.venueImage)
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: geometry.size.width, height: geometry.size.height + geometry.frame(in: .global).minY)
                        .clipped()
                        .offset(y: -geometry.frame(in: .global).minY)
                    }
                }
            }.frame(height: 300)
            VStack {
                HStack {
                    Text(self.title)
                        .font(.title)
                        .fontWeight(.bold)
                    Spacer()
                }.padding(.horizontal, 24)
                HStack {
                    Text(self.venueArea)
                        .foregroundColor(Color("bodyText"))
                    Spacer()
                }.padding(.horizontal, 24)

                VStack {
                    ForEach(self.venueProd) { gc in

                        VStack {
                            HStack {
                                    Text(gc.title)
                                        .font(.system(size: 17))
                                        .fontWeight(.semibold)
                                    Spacer()
                            }
                            HStack {
                                Text(gc.productDescription)
                                    .foregroundColor(Color("bodyText"))
                                    .font(.system(size: 15))
                                    .padding(.top, 5)
                                Spacer()
                            }
                            HStack {
                                Text("$\(gc.productPrice, specifier: "%.2f")")
                                Spacer()
                            }.padding(.top, 8)
                            Divider()
                        }.padding(.bottom, 8)

                    }
                    Spacer()
                }.padding(.horizontal, 24)
                    .padding(.top, 24)
                    .padding(.bottom, 60)
                Spacer()
            }
        }.edgesIgnoringSafeArea(.top)

       // AREA I'M TRYING TO MODIFY OPACITY ON SCROLL
        ZStack {

            GeometryReader { geometry in
            ZStack {
                    VStack {
                       Text("")
                           .frame(width: geometry.size.width, height: 120)
                        .background(Color.white)
                        .opacity(0.3                     )
                    Spacer()
                    } 
            }.edgesIgnoringSafeArea(.top) // Ends ZStack
            } // Ends Geometry Reader

            VStack {
                GeometryReader { gr in
                    HStack {
                        Button(action: {self.presentationMode.wrappedValue.dismiss()}) {
                            Image(systemName: "chevron.left")
                                .foregroundColor(.black)
                                .padding(.leading, 16)
                            HStack {
                                Text("Venues · Venue Details")
                                    .font(.system(size: 15))
                                    .fontWeight(.bold)
                                    .foregroundColor(Color.black)

                                    .padding()
                                Spacer()
                            }
                        }.frame(width: gr.size.width * 0.92, height: 48)
                            .background(Color.white)
                            .cornerRadius(8)

                    }.padding(.leading, 16)
                    Spacer()
                }
            }
            .padding(.top, 50)
            .edgesIgnoringSafeArea(.top)
        } // Ends Floating Menu ZStack

    } // Second ZStack
}

}

1个回答

3
这里是一个Idea的演示。
代码只展示了这个方法,由于简单所以可以很容易地集成/转换。所有背景颜色都只是为了更好的显示,计算可能更加复杂并包括动画,但是想法是一样的 - 可以使用GeometryProxy在全局坐标中读取图像的矩形,并根据此更改某些其他视图的透明度,通过对应的@State。
struct TestScrollDependentOpacity: View {

    @State private var barOpacity: Double = 0

    var body: some View {
        ZStack(alignment: .top) {
            mainContent
            floatingBar
        }
    }

    private var mainContent: some View {
        ScrollView {
            GeometryReader { g -> AnyView in
                let rect = g.frame(in: .global)
                DispatchQueue.main.async {
                    self.barOpacity = rect.maxY < 0 ? 0.5 : 0.0
                }
                return AnyView(Image(systemName: "sun.max")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .position(x: g.size.width / 2.0, y: g.size.height / 2.0))
            }
            .frame(height: 100).background(Color.yellow)

            VStack(alignment: .leading) {
                ForEach (0..<40) { i in
                    HStack {
                        Text("Text \(i)").padding()
                        Spacer()
                    }
                }
            }.background(Color.green)
        }
    }

    private var floatingBar: some View {
        HStack {
            Button("Left") { }
            Spacer()
            Button("Right") { }
        }
        .padding()
        .background(Color.white.opacity(barOpacity))
        .edgesIgnoringSafeArea(.top)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接