I added a how to use MTZReflectionSlider in the README of the project.
I added a how to use MTZReflectionSlider in the README of the project.
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).
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.
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!
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.
Today I gave a brief talk about all the different small projects I've been working on this semester. Slides
I've noticed recently that a lot of interfaces are adding a lot of interesting effects, animations and view behaviour. A lot of times these views simulate three dimensions. Some views move under other views and others stay on top. The issue is that these views are displayed in only two dimensions on a bitmap display (and probably will continue to be for the near future). Based on the way these views behave, the user has to put together a model of how these views relate to each other. Simulating lighting with shines and drop shadows can greatly help a user to put together a three dimensional model when only given two dimensions of information. This is just a reminder that the number of layers should be kept to a minimum to prevent a confusing model. Try building (or imagine) your interface with real world materials. Can it be done easily? If not, consider rethinking your app. It's much easier for your users to understand the behaviour of your app if it can be built using materials we use daily in the real world.
Let's take an app I've been thinking about a lot recently as an example: Rdio's iPhone app.
In the album view, it displays an arrow on the top left that appears to be on top of the album artwork. Towards the bottom of the square album artwork, information about the album is displayed. Below the album artwork is a list of the songs which is slightly cut off by the bottom of the screen. This hints that this view expands beyond the bounds of the screen and could be interacted with to reveal other content (a scrollview). Stuck to the very bottom of the view, a transparent box is displayed with information on the currently playing song. Before interacting with the interface, the user will likely assume that there are just a few main layers in this interface. One layer is a scrollview with the album artwork and track list. These elements are not currently overlapping and share similar information (in comparison to the rest of this screen, and especially compared to the rest of the app). Another layer, above the previously mentioned layer, contains navigation elements (the back button and the now playing information). Previously, I mentioned that the track list information appeared cut off, which hints that the size of this view might be larger than what is currently visible. The device itself is preventing the whole thing from being displayed at once and the screen is simply a window into a layer below the face of the device. This diagram from the manual from the 1984 Macintosh depicts how a scrollview works. Although it is obvious to most people that use a computer regularly, it's still very important to think about these things when designing interfaces.
Based on some previous experience with iOS and/or a three dimensional model of this view and understanding of physics, a user may place their finger on the view and slide it up on the screen. Just a moment after this, something amazing happens. The list of songs not only follows the user's finger, but it slides right over the album artwork! I bet you weren't expecting that!
Now the user's mental model of the app is broken. After all that excitement, the user and the interface both calm down.
The user now re-examines the app to see create a new mental model that works. The user still sees the arrow, but now with information on the album next to it. Hmm... this information must have moved to the top when we moved that list of songs to the top. The user still sees a similar looking list of songs with more content and still sees the now playing information stuck to the bottom. Let's adjust our model. There's actually even more layers than we previously imagined. It appears that the album artwork is below the track listing and the track listing window (that's essentially what a scrollview is) expands at the same time as the user scrolls. That's pretty complicated stuff! Also, when scrolling far enough, the track listing scrollview frame stop about 40px away from the top of the screen and disappears. It almost looks as if someone made a dark hole in the middle of the album artwork that the scrollview flys into. Or the album artwork is actually two layers that due to the user's limited two dimensional perspective appear to be on the same layer. Doing eye tricks like this is *not* good! Imagine trying to recreate this view using paper.
Hey! But, Matt! Don't give unsolicited critique like that. I also encourage anyone to critique my work and offer suggestions. It will help me improve my work and learn from other's experiences. Well, I won't keep you hanging. I'll offer a suggestions on how to fix this issue and create a much simpler behaving view. Instead of having the album artwork and track listings on two separate layers, have them in the same scrollview. When the track listing scrolls, the album artwork should scroll with it. The bottom of the album artwork should be attached to the top of the track listing. When scrolling far enough, the light colored back arrow, which is a design nightmare in it's own (detailed in my previous post), will be difficult to see against the light background of the track listing. A solid (translucent *may* work as well) bar containing the navigation interface elements will help create enough contrast to see these elements. Constructing this interface with real world materials is a much simpler task than before.
Don't sacrifice cognitive simplicity for fancy animations and interface element behaviour. There is probably a much simpler way of doing this with the same information and still have some fun, delighting animations and interface behaviour.
Note: I still haven't even talked about the animation of the views that brought us to this view in the first place (that may be a post for another day). Spoiler: it may be even more complicated!
This app does not have a lot of strong shadows, highlights, or textures. Most people would say it's very "simple". However, this app has one of the most complicated navigation and view behaviours in any app I've ever used.
stylistic simplicity != visual simplicity != actual simplicity
I started this back in February but never got around to finish it. Here's part 1:
Navigation is super important when designing a mobile app. Apple makes this pretty easy by providing great tools to do this, however, I still see many apps that don't follow iOS navigation conventions and it results in an almost unusable app. I'm going to talk about what the conventions are, and why they're used so you'll be ready to start designing better apps.
There are two main controls that deal with app navigation iOS.
The navigation bar shows the title of the currently displayed view (centered). It may also contain a button on the right to do certain tasks with the content below. Some common buttons displayed here are add, edit, compose, and action. The left of the navigation bar may have a back button to the previous view in the stack, if any. The back button should always have the title of the previous view controller and never the word "back". Doing this tells the user that they're navigating back, and where exactly they're navigating back to.
For example, viewing a contact in Contacts.app will show the contact's group in the back button. The animation is also very important. The title transforms into the label on the back button as it moves left.
A common trend is to remove the label and replace it with just an arrow for the sake of minimalism. Let's take a recent offender of this, the official Twitter app:
This is an awful idea as it now removes all context of the current view. How did you get to the current view? Some say "Well, you just navigated to that view! Of course you know where you are." That's not true as soon as you move to another app (or lock your device), and return to the app at a later time.
@flyosity in some cases it's useful as a way to know what you're looking at. <Inbox | Message vs. <Trash | Message— Loren Brichter (@lorenb) February 6, 2013
It is not always the case that you directly navigated to that view, and therefore it is even more important to know where you are and where the back button is taking you. Tap on a notification and you could be put a couple levels deep in an app.
Since people who design and build these app are likely to use their devices for many hours a day, and become extremely familiar with every view in all their apps, it is easy to forget about designing for those who may be new to (or less familiar with) the platform, or the app. The only thing that's changing when removing the back button label is clearing the screen of 1-2 words that hinders unfamiliar users and provides no additional benefits for power users.
Some apps will also require a tab bar, like Music.app. The tab bar allows you to separate out parts of your app. These items should change the current view and should be treated as their own. The only way to navigate between these views should be through the view controller (not the navigation bar). If the navigation bar behaves like a tree, the tab bar should simply be a collection of trees. Tapping on the tab bar item will bring you over to to the new tree. Tapping on a back button on the navigation bar should only move back in the tree but never to another tree!