Part 7 Making it possible to move knobs by dragging (panning) | Create the Color Picker with SwiftUI

This is a series of articles on creating a color picker in SwiftUI. In this article, we will implement a process that allows knobs to be moved with a drag (pan) gesture.

TOC

Use DragGesture in SwiftUI

In UIKit, the gesture of tracing a finger across the screen is called “panning” in iOS and iPadOS; in macOS, a similar operation performed with a mouse or trackpad is called “dragging.

SwiftUI calls them “drag gestures” because SwiftUI supports iOS, iPadOS, and macOS.

How to use DragGesture

To use drag gestures in SwiftUI, pass DragGesture to the gesture() modifier of the view in which you want to use the gesture.

var drag: some Gesture {
    DragGesture()
        .onChanged { dragValue in
            // Processing while dragging
        }
        .onEnded { dragValue in
            // Processing upon completion of a drag
        }
}

var body: some View {
        SomeView() // View using gestures
            .gesture(drag)
}

Implementation of knob movement process

Implement the process of moving a knob with a drag gesture. First, we implement the drag gesture process.

Implement the drag property

The process to be implemented is the same as for taps, calculating the current value from the X coordinate value of the coordinate at which the gesture is occurring and updating the value of the ColorPickerChannelModel.currentValue property.

Add the following code to the PickerGradationView.

struct PickerGradationView: View {
    
    var drag: some Gesture {
        DragGesture()
            .onChanged { dragValue in
                channel.changeCurrentValue(dragValue.location.x / gradation.viewSize.width)
                channel.clearFieldText()
            }
    }

Setting up gestures to the view

Sets the gesture obtained with the drag property to the view. The gesture() modifier is used to set the view. The code is as follows.

struct PickerGradationView: View {
    
    var body: some View {
        ZStack(alignment: .leading) {
            GeometryReader() { geometry in
                LinearGradient(gradient: Gradient(colors: [gradation.startColor, gradation.endColor]), startPoint: UnitPoint(x: 0, y: 0), endPoint: UnitPoint(x: 1, y: 0))
            }
            .frame(height: gradationHeigh)
            .background {
                GeometryReader { geometry in
                    Path { path in
                        Task.detached {
                            await updateViewSize(geometry.size)
                        }
                    }
                }
            }
            .onTapGesture { point in
                channel.currentValue = point.x / gradation.viewSize.width
                channel.clearFieldText()
            }
            .gesture(drag)

Check operation

Check it works: open ColorPicker.swift and drag on the gradient view in live preview. The knob will move to the position of the cursor you dragged, and the text field will also display the new current value.

Check operation with Xcode live preview
Check operation with Xcode live preview

Download the code

Click here to download the code created for this article.

Serialized Articles

This article is part of a series of articles titled “Create the Color Picker with SwiftUI”. Other articles in the series are here.

Create the Color Picker with SwiftUI

Let's share this post !

Author of this article

Akira Hayashiのアバター Akira Hayashi Representative, Software Engineer

I am an application developer loves programming. This blog is a tech blog, its articles are learning notes. In my work, I mainly focus on desktop and mobile application development, but I also write technical books and teach seminars. The websites of my work and books are here -> RK Kaihatsu.

TOC