I have a UI that allows someone to move a dial and the dial 'snaps' to each 'mark' on the dial.
I want to add sound to this and I've made a very short 'click' sound that is a fraction of a second.
I don't want to restrict how fast the user can rotate the dial, but I want the sound to play as the dial goes to each mark.
So I need a fast and responsive Audio library to use, however I also know I need to limit how many times it's played in case they spin it so quickly that otherwise the sound would become a constant noise, rather than distinct clicks.
I've seen comments that AVFoundation is too slow and that AVAudioEngine was going to give a better performance, but I'm still not sure if that's the best approach and how to tackle limiting the 'repetitive sound' so it's not just a horrendous noise.
I realise this is kind of something that games programmers deal with more than non-game iOS app developers deal with but I'm still stuck for an approach.
One approach...
Play the "click" sound every time the "current tick mark" changes.
This will be slightly different, depending on how you are animating the "dial" -- but the concept is the same. Let's use a scroll view for example.
For the scrollable content, we'll use a view and draw a vertical "tick mark" every 20-points, taller on even 100-points positions. We'll also overlay a view with a single vertical line near the horizontal center - so we want to play a "click" when a tick hits that line. And we'll size things so we can only scroll horizontally.
It will look like this:
and after scrolling a little:
When implementing
scrollViewDidScroll(...)with a typical scroll view, it is very easy to scroll quickly... so quickly, that the.contentOffset.xcan change 200+ points between calls.If we try to play the tick sound for every 20-points of change, we could be playing it 10 times at essentially the same time.
So, we could create a class property:
then calculate the current tick mark in
scrollViewDidScroll(...). If the values are different, play a tick sound:If we are scrolling / dragging very, very quickly, we don't need a click for every tick mark... because we are not seeing every tick mark cross the center-line.
As the scrolling decelerates -- or when dragging slowly -- we'll get a click on every tick.
Here's some quick example code to try out...
TickView - ticks every 20-points
MidLineView - vertical line to overlay on the scroll view
ViewController - example controller