How to layout properly in ZStack (I have visibility problem)?

393 views Asked by At

Here is reproducable small code below;

As you'll see when you run the demo code, the Element view does stay under Color.blue when dragged eventhough its above according to ZStack. By the way I also played with zIndex modifier but still no luck. Any solution you offer? Thanks all.

struct ContentView: View {
    
    var body: some View {
        GeometryReader { gr in
            
            ZStack {
            
                Color.blue.opacity(0.3)
                    .aspectRatio(1, contentMode: .fit)
                    .frame(width: gr.size.width)
                
                VStack {
                    Spacer()
                    ScrollView(.horizontal) {
                        HStack {
                            ForEach(1...15, id: \.self) { (idx) in
                                Element(index: idx)
                            }
                        }
                        .padding()
                    }
                    .background(Color.secondary.opacity(0.3))
                }
                
            }
        }
    }
    
}

struct Element: View {
    
    @State private var dragAmount = CGSize.zero
    
    var index: Int
    
    var body: some View {
        Rectangle()
            .frame(width: 80, height: 80)
            .overlay(Text("\(index)").bold().foregroundColor(.white))
            .offset(dragAmount)
            .gesture(
                DragGesture(coordinateSpace: .global)
                    .onChanged {
                        self.dragAmount = CGSize(width: $0.translation.width, height: $0.translation.height)
                    }
                    .onEnded { _ in
                        self.dragAmount = .zero
                    }
            )
    }
}

1

There are 1 answers

1
Asperi On BEST ANSWER

iOS 15.5: still valid

How can achieve my goal then, like dragging Element on different view (in this scenario Color.blue)

Actually we need to disable clipping by ScrollView.

Below is possible approach based on helper extensions from my other answers (https://stackoverflow.com/a/63322713/12299030 and https://stackoverflow.com/a/60855853/12299030)

demo

VStack {
    Spacer()
    ScrollView(.horizontal) {
        HStack {
            ForEach(1...15, id: \.self) { (idx) in
                Element(index: idx)
            }
        }
        .padding()
        .background(ScrollViewConfigurator {
          $0?.clipsToBounds = false              // << here !!
        })

        
    }
    .background(Color.secondary.opacity(0.3))
}