如何使用顶部的 ScrollView 使背景中的按钮可点击? [英] How to make Button in background tappable with ScrollView on top?

查看:30
本文介绍了如何使用顶部的 ScrollView 使背景中的按钮可点击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ScrollView 可以滑过标题,但我需要在标题中点击一个按钮.

I have a ScrollView that slides over the header, but I need a button in the header tappable.

这是它的样子:

我需要开始"按钮可点击,但由于 ScrollView 位于顶部,因此不可点击.我尝试使用 zIndex 但滚动不再出现在标题顶部.

I need the "Start" button tappable, but because the ScrollView is on top, it's not tappable. I tried playing with the zIndex but the scroll no longer occurred on top of the header.

这是示例代码:

struct ContentView: View {
    @State private var isPresented = false
    @State private var headerHeight: CGFloat = 0

    var body: some View {
        ZStack(alignment: .top) {
            VStack {
                Button("Start") {
                    isPresented = true
                }
                .padding()
                .frame(maxWidth: .infinity)
                .foregroundColor(.white)
                .background(Color.blue)
                .cornerRadius(16)
            }
            .padding(80)
            .background(Color(.label).ignoresSafeArea())
            .assign(heightTo: $headerHeight)
            ScrollView(showsIndicators: false) {
                Spacer()
                    .frame(height: headerHeight)
                VStack {
                    ForEach((0...50), id: \.self) {
                        Text("Some text \($0)")
                    }
                }
                .padding()
                .frame(maxWidth: .infinity)
                .background(Color(.white))
            }
        }
        .navigationBarHidden(true)
        .alert(isPresented: $isPresented) {
            Alert(title: Text("Button tapped"))
        }
    }
}

extension View {
    /// Binds the height of the view to a property.
    func assign(heightTo height: Binding<CGFloat>) -> some View {
        background(
            GeometryReader { geometry in
                Color.clear.onAppear {
                    height.wrappedValue = geometry.size.height
                }
            }
        )
    }
}

如何在使滚动视图滑过标题时实现这一点?

How can this be achieved while making the scroll view slide over the header?

推荐答案

Version 2.0.0


我决定更新我的答案,因为如果我把它们放在同一个答案中可能会造成混淆,我把它放在这里,以使代码和答案更加清晰易读.关于新的更新,基本相同,只是加强版!

Version 2.0.0


I decided to updated my answer and because it can be confused if i put them in same answer, I am putting it here, to keep codes and answers much clear and easy to read. about new update, it is basically the same way but a souped-up version!

import SwiftUI

struct ContentView: View {
    
    @State private var isPresented: Bool = Bool()
    @State private var offsetY: CGFloat = CGFloat()
    @State private var headerHeight: CGFloat = CGFloat()
    
    var body: some View {
        
        GeometryReader { screenGeometry in
            
            ZStack {
                
                Color.yellow.ignoresSafeArea()
                
                ScrollView(showsIndicators: false) {
                    
                    VStack(spacing: 0.0) {
                        
                        Color.clear                         // Test if we are in Center! >> change Color.clear to Color.blue and uncomment down code for Capsule() to see it!
                            .frame(height: headerHeight)
                            //.overlay(Capsule().frame(height: 2.0))
                            .overlay( HeaderView(isPresented: $isPresented)
                                        .background( GeometryReader { proxy in Color.clear.onAppear { headerHeight = proxy.size.height } } )
                                        .offset(y: headerHeight + screenGeometry.safeAreaInsets.top - offsetY))
                        
                        ZStack {
                            
                            Color.white.cornerRadius(20.0)
                            
                            VStack { ForEach((0...30), id: \.self) { item in Text("item " + item.description); Divider().padding(.horizontal) } }.padding(.top)
                            
                        }
                        .padding(.horizontal)
                        .overlay( GeometryReader { proxy in Color.clear.onChange(of: proxy.frame(in: .global).minY) { newValue in offsetY = newValue } } )
                        
                    }
                    
                }
                
            }
            .position(x: screenGeometry.size.width/2, y: screenGeometry.size.height/2)
            .alert(isPresented: $isPresented) { Alert(title: Text("Button tapped")) }
            .statusBar(hidden: true)
            
        }
        .shadow(radius: 10.0)
        
    }
    
}


struct HeaderView: View {
    
    @Binding var isPresented: Bool
    
    var body: some View {
        
        ZStack {
            
            Color.clear
            
            VStack(spacing: 20.0) {
                
                button(color: Color(UIColor.systemTeal))
                
                Text("Some text 1").bold()
                
                Text("Some text 2").bold()
                
                button(color: Color(UIColor.green))
                
                Text("Some text 3").bold()
                
                Text("Some text 4").bold()
                
                button(color: Color.purple)
                
            }
            
        }
        .padding()
        
    }
    
    func button(color: Color) -> some View {
        
        return Button(action: { isPresented.toggle() }, label: {
            
            Text("Start")
                .bold()
                .padding()
                .shadow(radius: 10.0)
                .frame(maxWidth: .infinity)
                .background(color)
                .foregroundColor(.white)
                .cornerRadius(16)
            
        })
        
    }
    
}

这篇关于如何使用顶部的 ScrollView 使背景中的按钮可点击?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆