4

I have container view which can be draged around and it has scrollview inside with bunch of buttons. When i drag the container view scrollViews starts to jump up and down weirdly, also buttons' hitboxes start be way off from actual buttons. (You can see my gif) But when I touch scrollview everything gets back to normal. Demo weird scrollview

This code is purely for testing

That's the main view

    struct ContentView: View {
    @State var width : CGFloat = 300
    @State var height : CGFloat = 300
    var body: some View {
        VStack{
            SecondView(width: width, height: height){
                ScrollView{
                    VStack{
                        ForEach(0...10, id : \.self){ i in
                            
                            TestButton(number: i)
                            
                        }
                    }
                }
            }
            Slider(value: $width, in: 100...500)
            Slider(value: $height, in: 100...500)
        }
    }
}

That's the dragable view

    struct SecondView<Content : View> : View {
    var width : CGFloat
    var height : CGFloat
    var content : () -> Content
    @GestureState private var dragState = DragState.inactive
    @State var position : CGSize = CGSize(width: 0, height: 0)
    var body : some View {
        let dragGesture = DragGesture().updating($dragState){ drag, state, transition in
            state = .dragging(translation: drag.translation)
            
        }.onEnded({drag in
            self.position.height+=drag.translation.height
            self.position.width+=drag.translation.width
        })
        return VStack{
            Handle()
            
            content().padding()
            
        }.frame(width: width, height: height).background(Color.yellow).cornerRadius(10)
            .offset(x: self.position.width + dragState.translation.width, y: self.position.height + dragState.translation.height)
            .gesture(dragGesture)
        
    }
    
    enum DragState {
        case inactive
        case dragging(translation : CGSize)
        
        
        var translation : CGSize {
            switch self {
            case .inactive:
                return .zero
            case .dragging(let translation):
                return translation
            }
        }
        
        var isDragging : Bool {
            switch self {
            case .inactive:
                return false
            case .dragging:
                return true
            }
        }
    }
}

I'm not sure if it is a bug or it's me doing something wrong, but looks like bug Thanks in advance for answers and suggestions

1 Answer 1

2

The .offset modifier does not change views layout, so moved view really remains on the same place and hit areas remains on same place, it just drawn in different location.

Thus .offset does not fit for your goal, instead refactor to use .position, which really changes view hierarchy (but affects entire layout as well, so your floating pane should be placed in separated ZStack to avoid others).

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.