Home > database >  How to make a clear SwiftUI view block the scrollview underneath it
How to make a clear SwiftUI view block the scrollview underneath it

Time:05-09

So I have a ZStack that contains a ScrollView on the bottom and an HStack that's aligned at the top. It looks something like this:

ZStack {
  ScrollView {
    //Content
  }
  VStack {
    HStack {
      Spacer()
      Circle()
        .frame(width: 30, height: 30)
      Spacer()
    }
    Spacer()
  }
}

Now, I want that HStack to block any interaction with the ScrollView beneath it. I've noticed that when I set the background on the HStack to a non-clear color, it behaves as I'd like it to. However, if the background is clear, then the touches go through the HStack and interact with the ScrollView beneath it. I've also tried using .allowsHitTesting(true) on the HStack with no luck.

Any help is much appreciated!

CodePudding user response:

"...I've noticed that when I set the background on the HStack to a non-clear color, it behaves as I'd like it to.", then you could use Color.white.opacity(0.001) instead of Color.clear or non-clear color

CodePudding user response:

You can easily accomplish this by putting it in a VStack instead of a ZStack. The touches will be ignored as it's above the ScrollView. You can also have a look at .layoutPriority(), it may also be useful. Documentation is scrollview

struct ContentView: View {
    var body: some View {
        VStack {
            HStack {
                Spacer()
                Circle()
                    .foregroundColor(Color.blue)
                    .frame(width: 30, height: 30)
                Spacer()
            }
            .padding()
            // or this does the same thing as the HStack two spacers
            /*
            Circle()
                .foregroundColor(Color.blue)
                .frame(width: 30, height: 30)
                .frame(minWidth: 0, maxWidth: .infinity)
             */
            Spacer()
            ScrollView {
                ForEach(1..<11) { value in
                    Text("\(value)")
                }
            }
        }
    }
}

CodePudding user response:

Just add content shape for entire HStack that marks area interactive and will not pass taps through:

HStack {
  Spacer()
  Circle()
    .frame(width: 30, height: 30)
  Spacer()
}
.contentShape(Rectangle())       // << here !!
  • Related