Matt Zanchelli

April 16 2013

Tilt-Controlled Brushed Metal Slider Knob

In iOS 6, Music.app added a wonderful tilt-controlled brushed metal slider knob. Upon tilting the device, the lighting of this UI element changes. There are a few other elements that react to device motion and adjust accordingly, but I'll be focusing on just the knob in this post. This specific UI element is not available for use for anyone outside of Apple, so I decided to try and make an open source version so others may use it.

There's currently an open source version of this created by Teehan+Lax. I downloaded it only to be disappointed. The gradient not only looks less than attractive, it also looks more like a pinwheel than shine on a knob. It often lags behind (even on iPhone 5) and doesn't animate at all on older devices (my iPhone 4).

TLTiltSlider
A short video of their implementation
(Watch on Vimeo)

I decided this version isn't enough and I needed to make my own. I originally tried to use CoreGraphics to draw angular gradients every 1/60th of a second. This provided great results on an iPhone 5, but was awfully slow on older models. After many rewrites and some research, I decided to just use stacked UIImageViews with transparency. This certainly improved performance. Thanks to [UIView setAnimationBeginsFromCurrentState:YES], I can always get 60fps animations and not have animations lagging behind. I also check to make sure that the difference in motion is significant enough to even continue with the rest of the calculations. Where did I come up with 0.002210f for the minimum change necessary in motion? I calculated the circumference of the slider and how much motion would be necessary to move the shine layers 1/3 of a pixel. This is enough to prevent a lot of code being executed when the device is very still. There could still probably be some improvements to this. I could take into consideration whether or not the device is retina. Have any ideas? Fork it and help out, please.

MTZTiltReflectionSlider
A short video of my implemtation
(Watch on Vimeo)

How does this compare to Apple's implementation? Turns out, it is very similar. While I was debugging my implementation, I turned on "Color Misaligned Images" for a yellow cast to be put over misaligned images. I decided to use this while Music.app was open to see if they are using image views as well. The answer is, yes!

MTZTiltReflectionSlider

iOS 6 Music.app

Apple seems to be using three image views on top of the base, whereas I'm only using two. From lots of playing around, it appears that Apple is using an extra layer not for a shine, but a dark spot on the knob. It looks like this image's opacity comes in an out quickly. Because of this, it is not only less accurate, but also makes the animation jittery at times. In this video (Watch on Vimeo), I slowly tilt the device and the gradient jitters. This could be better. Apple's implementation is also backwards. The x and y coordinates are backwards. When moving the device's pitch, the gradient rotates clockwise/counter-clockwise. The rotation should correspond to the device's roll. Try this with a knob (there's one on the bottom of Magic Mouse) or the bottom of a frying pan under controlled lighting. In the case you don't have immediate access to one, here's a video of me demonstrating lighting on a small brushed metal knob (the side of Apple wireless keyboard) (Watch on Vimeo).

You'll notice that when changing the roll of the knob, the shines rotate in the same direction (against the roll) and one of the shines fades away slowly. This is how my implementation works.

Check out, download, use my implementation