Home

Awesome

CI COV License: MIT

Knob

Simple slider-like control that depicts its path as an arc using CoreAnimation layers. Supports both iOS and macOS platforms.

<table> <tr> <td><img src="https://github.com/bradhowes/Knob/blob/main/KnobMove.gif?raw=true" alt="Animation of knob"/></td> <td><img src="https://github.com/bradhowes/Knob/blob/main/example.png?raw=true" alt="Knobs in SoundFonts app"/></td> </tr> </table>

Like a slider, touch movements in the control change the value. For this implementation:

The above picture was taken from my SoundFonts iOS app where the knobs control various audio effects settings.

Included is a playground for playing with a knob.

Versions

There are two major versions that have a slight change in the API. Originally (up to v1.6.0) the width of the knob's track and indicator were given as notional pixel values. With v2.0.0, this changed to factor which is multiplied with the minimum of the bounds width and height values to arrive at the width value to use. This allows for scaling of the knob features as the bounds of the knob changes.

Configuration

Arc angles are explained well in the UIBezierPath documentation. In brief, an angle of 0 will extend along the X axis, whereas an angle of π/2 will extend along the negative Y axis.

The draw method used to render the knob's arc path draws in a clockwise fashion, so the end arc angle must be greater than the start arc angle. The default values leave the opening in the arc path centered around the negative Y axis (pointing down), with an arc distance of 2/16 of the circumference.

Mouse/Touch Tracking

As one would expect, a touch in the knob's view area is tracked and any changes are reported to any registered actions:

SwiftUI Support

The package also includes a SwiftUI implementation: KnobView. The defaults should be good enough to start with, but there are modifiers you can apply to your KnobView to configure the look you want. The KnobView constructor requires two state bindings, one for the knob's value and another for the knob's manipulating flag. Additionally, you can provide the minimumValue and maximumValue values to override the defaults of 0.0 and 1.0 respectively.

KnobView(value: $volumeValue, manipulating: $volumeManipulating, minimum: 0.0, maximum: 1.0)
  .trackStyle(width: trackWidth, color: trackColor)
  .progressStyle(width: progressWidth, color: progressColor)
  .indicatorStyle(width: progressWidth, color: progressColor, length: 0.3)

Demo Apps

The KnobDemo folder contains an Xcode project which you can open to build simple demo apps for macOS and iOS platforms. These also contain UI tests that make sure that the knobs properly track and report out their values.

The demo apps use SwiftUI for their view definitions. They both contain a ContentView properly wires up two KnobView instances with a Text view that shows the value of a KnobView.