admaDIC App Development & IT Solutions

Dragging a SwiftUI View

by Annett Schwarze | 2025-10-03

Using `DragGesture` a floating movable `Button` can be easily implemented. Use the `.offset()` view modifier to shift the position of the movable view. Use the `DragGesture` to record dragging events and adjust the offset for the movable view.

When the drag gesture begins, a start offset is stored. Subsequent drag translations are used to calculate the current offset based on the start value and the dragging translation. When the drag gesture ends, the busy state is reset to be ready for the next drag.

        
import SwiftUI

struct SampleDraggingOverlayView: View {

    @State private var dragOffset: CGSize = .zero
    @State private var dragStart: CGSize = .zero
    @State private var dragBusy: Bool = false

    var body: some View {
        Text("Sample Dragging Overlay")
            .font(.largeTitle)
        VStack {
            Text("You can drag the floating button")
                .padding()
            Spacer()
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background {
            Color(white: 0.95)
                .ignoresSafeArea(edges: [.leading, .trailing, .bottom])
        }
        .overlay {
            GeometryReader { geometry in
                HStack(spacing: 12) {
                    Text("Drag me")
                    Button(action: {
                        reset(geometry.size)
                    }, label: {
                        Image(systemName: "sun.max")
                    })
                }
                .onAppear(perform: {
                    reset(geometry.size)
                })
                .padding()
                .background {
                    Color(white: 0.99)
                }
                .clipShape(Capsule())
                .shadow(radius: 6)
                .overlay(content: {
                    Capsule()
                        .inset(by: 1)
                        .stroke(dragBusy ? Color.red : Color.blue, lineWidth: 2)
                })
                .offset(dragOffset)
                .gesture(
                    DragGesture()
                        .onChanged({ value in
                            if !dragBusy {
                                dragStart = dragOffset
                                dragBusy = true
                            }
                            let newOffset = CGSize(
                                width: dragStart.width + value.translation.width,
                                height: dragStart.height + value.translation.height)
                            dragOffset = newOffset
                        })
                        .onEnded({ value in
                            dragBusy = false
                            dragStart = .zero
                        })
                )
                .padding(8)
            }
        }
    }

    private func reset(_ size: CGSize) {
        dragOffset = CGSize(width: size.width / 2 * 0.3, height: size.height / 2 * 0.3)
    }
}

#Preview {
    SampleDraggingOverlayView()
}
    
Dragging a SwiftUI View

 

www.admadic.de | webmaster@admadic.de | Legal Notice and Trademarks | Privacy
© 2005-2007 - admaDIC | All Rights Reserved
All other trademarks and/or registered trademarks are the property of their respective owners
Last Change: Fri Oct 3 08:49:59 2025 GMT