Updating for Modern iOS Design – A Case Study

TL;DR — Check out the pictures and videos on this page, and you’ll see how I adapted the basic circular menu of Click version 1 to fit the new iOS 7 design aesthetic, not just in visual terms, but also in interaction style: clean and almost chrome free, with more color, more seamless transitions, new inertial/physics-y interactions and direct manipulation transitions.

 

Hello Again!

As you can probably imagine, a LOT has happened in my life in the last almost two years since I’ve posted on this blog (and therefore also on iDevBlogADay)! And most of it has not been iOS development related, so I guess that’s my excuse for such an incredibly long time between posts. But, I have been working when I have the time, and I just released a new version of my iPhone app called Click Metronome. The original version was the topic of many of my posts here on this blog, especially about the design of the circular control. For this post, I thought it might be interesting to explore some of the design changes I made to Click when releasing version 2. The principles behind the design – and the features of the app – are largely the same, but the actual look and feel is completely different. So first, how about a look at a screenshot from version 1, and then the promo video for the new version for iOS 7+. Can you guess which is which? 🙂

 

Screenshot 2014.08.02 13.38.42

 

Circular Menu

At the time, I was really happy with how Click turned out. Then – and now – there’s a lot of metronome apps out there, but they seem to either be too simple and missing key features, or feature-rich but with a screen that’s completely full of buttons. So, one of my main goals for Click was to offer all the main features people would want – wide tempo range, variety of time signatures, accent options, etc. – and make them quickly accessible, but without cluttering up the screen with tons and tons of buttons. So, after much iteration, I came up with this menu system that showed all the current settings around a small circle. Then, the user taps an item and all the options for that setting are revealed in the circle, ready to be set by rotating. Here’s that menu in action in version 1 and version 2 (watch in slo-mo):

 

Click1MenuSmall

Click2MenuTapSmall

 

Version 1 Problems and Fixes:

I felt like I accomplished the goals I had set out, and watching people as they used the app, they always eventually figured out how to use it. But, it was never as intuitive and easy as I had hoped. As I got feedback from others, and as I thought more and more about the app myself, I came up with a whole list of problems with the implementation of the menu:

Continue reading “Updating for Modern iOS Design – A Case Study”

Click – A Postmortem

The App

My latest app, an iPhone metronome called Click, has been out for two months now, so I thought this would be a good time to do a little postmortem reflection on the development process, the launch, and some thoughts for the future. I’ve discussed some of the development and design of the app before on my blog, but I haven’t yet done much discussion of how it all turned out. So, here goes…if you’re mostly just interested in the numbers, then skip to the end (although I’ll give you a hint: they’re not too large).

What Went Well

1. The Design

There are still some things I want to tweak, but overall I’m very pleased with how the general look and feel of the app came out. It was incredibly satisfying to go through the whole process of brainstorming ideas, testing them out, and then finally settling on a design and control scheme and actually seeing it come to life. It was definitely a learning process, and even though it was slow going, I can look back on my time spent with this project and know that it wasn’t wasted time. I was focused on creating a certain “look” for this specific app, but everything I learned about Core Graphics, UIKit, and Photoshop is instantly transferable and applicable to future projects. There were certainly times that I wanted to give up on the customization, throw in a few stock UIButtons and ScrollViews and just ship this stupid thing, but in the end I’m glad I stuck it out! Being able to turn your vision of what something could be into a real, working product is, for me, one of the greatest joys of software development.

2. The Features/Scope

I spent quite a lot of time and effort thinking through exactly which options and features I wanted to include in this app. The only real required feature of a metronome is that it produce sound at a regular interval (and yes, probably also with some type of visual feedback), and the only required option is to be able to set the tempo to the desired speed. This is all that a traditional hardware metronome does. But modern metronomes – of the software and the hardware variety – have so much more audio flexibility: time signatures, variable accent patterns, subdivide the beat in various rhythms, multiple sounds, storing setups for creating set lists or practice routines, programming longer sequences for specific songs, and on and on. There’s also many varieties of visual feedback available, especially in the realm of software metronomes. I made the decision that one of the key distinguishing features of Click would be the ability to select Continue reading “Click – A Postmortem”

Some Good News and Some Bad News

I’m sure everyone is busy playing with the new bits from Apple right now, or lusting over the new hardware just announced, so I’m not sure who all will see this, but it’s my slot today for iDevBlogADay, and I’ve got some news to share, so I’m going for it!

I’m so mad at myself right now. The good news is, my new metronome app “Click” was just approved and is Ready for Sale!! The bad news is, I used a promo code to download it before releasing it for sale, and… it’s got a bug. A big ol’ freaking whopper of a bug. Somehow as I finalized my image assets, one of the resources had the wrong name in the Nib file – there was an “@2x” left on the end of the image name in the Nib configuration for the UIImageView. The app runs and loads fine in the simulator, and I swear the final build worked fine on my device too, but apparently the App Store release build is more picky and couldn’t locate the resource. So, one of the key pieces of the interface is invisible. So guess what? I’ll be waiting another week at least for another review. I could possibly ask for an expedited review, seeing as this is a “critical bug,” but the problem is the app isn’t actually even for sale yet, so it’s not like the bug is actually “live.” I don’t really wanna push my luck and/or annoy the review team now and then really need an expedited review later. So, one lesson is, keep testing the crap out of your app even after you submit, and you just might catch something and be able to developer reject your binary before the review starts. The other, real moral of the story is: delay the release of your app at least enough to generate a promo code and try out the released version for yourself. I have no idea when promo codes started working for apps before they’re actually released, but it certainly saved me this time! My thanks to @wtrebella for bringing this to my attention when he was tweeting about releasing Polymer.

I must say though, this isn’t all bad. I’ve been working on this app for over a year. I’ve been wanting to integrate a quality metronome into another app of my, theDrumDictionary, and in future music-related apps. So, this was supposed to be a quick side project in learning Core Audio and how to make a metronome, and since I was going to do it anyway, I figured, why not release a standalone metronome app too? But I didn’t want to make just another metronome app, and as I explored how to differentiate mine from the existing options, it sort of exploded into this very large project with difficult to implement (for me) custom controls and a large amount of Photoshop time designing a unique UI. Needless to say, I’m ready to get this thing out there and see what happens! When it comes to an initial release, I actually came to appreciate the sort of built in waiting period of the app store review time. Being forced to stop coding, it was a great chance for me to finalize my press materials and continue to get the word out about the new app. I was expecting to be done a *lot* sooner than how it turned out, and by the time I submitted the app for review, I knew I was going to be running right up against WWDC. Who’s going to care about some no-name company’s metronome app in the middle of big hardware and software announcements?! If approved during dub-dub, how long should I wait to release the app? Or should I release the app, and just wait until later to do press releases, etc.? Or is it really most beneficial to do a launch all at once – app appearing on new releases, press release, etc? (Great articles from Justine Pratt on marketing, by the way!) Well, now I don’t have much choice! I’ve probably got another whole week to keep up the marketing prep, spread the word to existing DrumDictionary customers, etc., and there’s not much worry about WWDC anymore. I’ve got to release this sometime, and a whole week after the big keynote seems like as good a time as any to me; it’s certainly much better than anytime this week. And, I can confidently run a full on launch blitz with no fear that I’m messing it up by separating the app release from the press release OR driving myself crazy as I wait for days for the right marketing timing knowing that it’s just sitting there ready waiting for me to change the availability date. I suppose I shouldn’t be too mad about it after all! (but let’s face it, I’m pretty pissed). Anyway, maybe this gives you something to think about before you release your next app! And, if you’re curious, head on over to my new Gig Bag Apps website and check out the trailer for Click. Maybe it’ll be a hit; if I ever actually release it 🙂

Photoshop Layer Comps

Just a quick Photoshop tip today, but it’s something I’ve been making extensive use of the last few weeks, so I thought I’d share. If you happened to read my last post and/or watch the video, you would have seen that in my new metronome app, I’m handling interface rotation in a somewhat different way than most apps. Rather than using the standard system autorotations – using the usual springs and struts in Interface Builder or the UIView’s autoresizingMask property – I’m leaving the basic layout of the controls the same and just rotating the contents. It’s kind of hard to describe, so if that doesn’t make sense, skip to about the 10:00 mark on this video.

Here’s the gist of the code to make this happen:

  • In the main ViewController’s shouldAutorotate method I only return YES for  UIInterfaceOrientationLandscapeRight, the same orientation the app launches in. Meaning, the view controller will not do any auto-rotating once it’s loaded into its initial state.
  • I’ve registered for the UIDeviceOrientationDidChangeNotification. Even though the View Controller will not do anything automatically when the device is rotated, the system will still generate these notifications when the orientation changes.
  • When I receive this notification, I pass the message along, and the individual views apply whatever sort of rotation transform they need to in order to remain “right side up.”
  • If the Status Bar is visible, you can also programmatically set its orientation with:[[UIApplication sharedApplication] setStatusBarOrientation:(UIInterfaceOrientation)orientation animated:YES];

What this means from a design perspective, is that the UIImageViews themselves, which contain the main interface chrome, do NOT rotate at all. So, here on the right is what the main control frame looks in the launch orientation – notice the shadows, gradients, etc. all use the “canonical” iOS 90 degree light source.

Let’s say the user then rotates to LandscapeLeft – my subviews will rotate themselves, but the image will stay exactly the same. The image on the left is the same, but rotated 180 degrees. It’s strange how much different – and more noticeable – the light/shadow/gradient effects are when they’re flipped around the wrong way!

So, in order to maintain the right look, what I need to do is create separate images for each orientation and load these in as part of my custom rotation handling. Here’s where Photoshop layer comps come in. What they let you do is take snapshots of certain aspects of your document state and then reload them with one click. For example, in my case, I’ve set up one Layer Comp for each of the four orientations I’ll support. Here’s the workflow:

  • Setup the document for the current orientation. In the case of LandscapeRight, that means 90 degree light sources for all drop shadows, gradients that go light to dark from top to bottom, etc.
  • In the Layer Comps window – add it to the toolbar from the Window menu if you don’t see it – select New Layer Comp from the pulldown menu.
  • In the dialogue box that opens, give your comp a name, select which parts of the document state you want to be saved as part of the snapshot, and add any helpful comments you might have. 
  • For this particular case, I’ve told the Layer Comp to only save the Layer Styles of the document’s layers.
  • Repeat the process for each orientation, setting the light sources, gradients, etc. on the Layer Styles, and then saving it as a new Layer Comp.

By using vector/smart objects and layer styles – you are doing that aren’t you? – the exact same set of objects and layers is used for every orientation. I’m free to adjust the positioning, size, and shape of the objects, and then, when it comes time to export for each orientation, I just click through the four Layer Comps one by one, and all my light and shadow effects are applied instantly to all objects. It takes a bit of work to setup, but once it’s ready, it saves huge amounts of time over going to each object individually and resetting the properties every time I want to make a change in the design and re-export for each orientation. For things like the “Tap,” “+,” and “-” labels, and for different button states, I also have a set of Layer Comps which control layer visibility. So, for example, if I need to re-export the image for the “pressed” tap button – I hit the Layer Comp for the orientation I want, which loads the correct layer styles, then hit the “Tap Button Pressed” layer comp which won’t affect the layer styles, but will hide the normal Tap button layers and show the pressed ones. Two clicks and I’m ready to export. So, that’s how I’ve been using Layer Comps in my particular case to speed up my design workflow – hopefully it gives you some ideas for how you might be able to use them in your own workflow!

Introducing: Click

I’ve mentioned my upcoming metronome app a few times before on the blog here, but now that I’m getting closer to completion, I thought I’d take a moment and give it a formal introduction. It’s still very much a work in progress, so don’t take this as a press release or a marketing video. It’s more like, a behind the scenes intro from a developers perspective. So, without further ado, here we go!

The Name

“Click,” or perhaps with a subtitle, “Click – Metronome” is the title of my new app. Honestly, I’m not 100% happy with this name. To the general population, it’s probably pretty ambiguous, hence the subtitle. But among musicians – who would be the majority of those purchasing this app – a “click” is a common way of referring to a metronome. Basically, there’s a lot of metronome apps out there, and this was one of the only non-corny, non-“punny”, simple, to-the-point names that was not yet taken.

The Design

It’s easier to show you this than to try to explain it – so jump to the video if you want – but I want to share some of my rationale/process of design for this app. There’s lots of metronomes out there (are you seeing a theme yet?), but from a design perspective, most of them are just plain crap. Now, I’m no design expert by any means – it’s only been in the process of making this app that I’ve begun to truly dig in and study principles of UI and UX design. So, that being said, if even I can see  – and articulate why – these apps are crap, then they must actually crap!! Seriously though, there are some good metronomes out there, but there’s definitely room for more quality ones.

One of the issues I see, even with the good ones, is that they want to be powerful and give the user a lot of options, but in doing so they sacrifice usability. Even the easy to use ones still end up filling the entire screen with buttons and cram the visual part of the metronome itself into a small section of the screen. So first and foremost, I wanted to find a way to give plenty of options, but still leave lots of screen space for the metronome itself. In that respect, I’m very pleased with how the circular menu/selector has worked out for this.

As far as the actual *look* of the design goes, I’m shooting for something with both realism AND digital “flexibility.” It’s realistic in the sense that the app looks like a real object – with shadows, highlights, texture, some physical buttons and handles, etc. But, it’s not overly skeuomorphic and doesn’t necessarily directly resemble any real-life metronome. The main controls and the central view are basically just “screens” upon which I can display anything I want, completely unrestrained by what would or would not work on a physical device.

Another thing I wanted to do with this app is minimize the use of words or labels. Obviously, there are a lot of numbers used – no way around that really when you’re talking about setting specific tempos and time signatures – but there’s very few words. As long as I can find appropriate symbols to communicate what each thing does, I think this will give the app a nice, clean, accessible quality. Not to mention how much easier localization will be when there’s only a handful of words in the whole app!

The Video

Enough talk, just watch! Not everything is working yet, and even the working things are still in progress, but this will hopefully give a nice preview of what’s coming up. I’d love to hear any feedback you’ve got, positive or negative! Thanks for watching.

—-  Yikes! The video quality did not turn out too well after compression. Oh well, you get the idea. It looks *great* on the device, I promise  🙂  —-

P.S. – Wanna Help Test?

If you’re interested in helping beta test Click, follow the link here to Test Flight. I may not be able to take everybody – Apple’s 100 device limit is turning out to be more restrictive than I realized at first – but I will take whoever I can. If you’re a musician or otherwise particularly “qualified” to test this app, that will help me narrow it down if I need to, but it’s not a requirement. Thanks!

Test Flight – http://bit.ly/zjcd0g

A Debugging Lament. And, Totally Unrelated – Simple Gesture Recognition

When Debugging Sucks (More than usual)

For my iDevBlogADay post today, I considered writing a tutorial about debugging, but ultimately decided against it. For one thing, it would most likely have just ended up being me venting about this freakin’ bug that plagued me for months on and off. For another thing, who would really trust a lesson in debugging written by a guy who took 4 months to solve one little bug 🙂  So, I’ll get on to my main topic in a minute, but first, a few quick tips from my experience:

1. Just because the bug first appears when you start adding animations, doesn’t mean it’s a problem with how you calculate your animations; it could have been hiding there in the background all along and only appeared when you started trying to automate some things instead of reacting directly to user input…grrr

2. Just because the bug appears to be a math error, it may not be. Remember that tiny little “if…else” statement that you set up WAY back at the beginning of this project? Yeah, you didn’t account for the rare, but oh-so-important case when you’ll actually need to run the code in BOTH branches. “if…if” FTW!

3. When your “bug” is actually two very similar bugs that manifest in nearly identical ways, but are caused by slightly different circumstances, just face it, you better start praying and offering some sacrifices to the programming gods, ’cause they are obviously angry with you. Good luck trying to find a way to reliably reproduce THAT issue!

4. Do not, I repeat, do not stop digging until you *know* that you’ve found the root cause. “Well, the problem is happening somewhere in this general area, so maybe if I rework this part right here and see what…” STOP!! Keep. Searching. Now, it’s one thing to make adjustments as a part of the bug-finding process. It’s a whole other thing to just start changing things hoping the bug will disappear. It’s not like I didn’t know that before, it’s just that, *hangs head in shame* I got so desperate and…sniffle…sob…*takes a deep breath*…OK, I’m back. On the bright side, my shot-in-the-dark refactoring adventures DID result in a much better understanding of my code and in the end, a simpler, cleaner implementation.

Now, onto the main topic: simple gesture recognition techniques

Tap, Drag, Hold

iDevices are all about multitouch. It’s one of the breakthrough features that made the original iPhone so unique, and it’s implementation in iOS has been copied by every other similar smartphone and tablet out there. Over the years, as people got used to the technology, and especially after the introduction of the larger screen iPad, gestures have become a huge part of the iOS experience. Personally, I have yet to dive into programming with UIGestureRecognizers, but I’ve read the docs and watched the WWDC videos, and it really as amazing. If you’re looking to implement complex, multi-touch, multi-tap gestures on many overlapping and interacting views, then there is some really powerful stuff in there. But what if you don’t need all that? For me, the most important gestures for my metronome app are simple taps and drags, along with translating their locations into angles around a circle. I’ve demonstrated the basics of this second part in this post about rotating a circle along with a user touch. Rather than learn a whole new framework and go through the process of attaching multiple gesture recognizers to my view, with different methods for different gestures, I was looking for a simple way to implement single taps and drags right within the UIControl touch handling methods I was already using. Turns out, it’s not hard at all. (I’m using a UIControl subclass for this, but there are very similar touch handling methods on a basic UIView that will get you the same results).

Touch handling for UIControls consists of 4 main methods:

-beginTrackingWithTouch:withEvent:

-continueTrackingWithTouch:withEvent:

-endTrackingWithTouch:withEvent:

-cancelTrackingWithTouch:withEvent:

This particular implementation does not handle multiple touches, so the “multipleTouchEnabled” property of the view should be set to NO. In the -beginTracking method, we’ll grab the location of the touch that’s passed in with, conveniently enough, “[touch locationInView:self]” and store it in a CGPoint variable. We’ll also need a “tap” flag, which we’ll set here to YES.

For however long this individual touch stays down, we’ll get calls in the -continueTracking method each time the touch moves. Compare the new location to the initial touch location we stored above, and – using good old Pythagorean Theorem – calculate the distance between them. If the touch has moved more than some predefined distance, then set the “tap” flag to NO, and continue on with whatever tracking you need to do. In my case, I start tracking the angle of rotation around the center and send this info to a delegate.

In the -endTracking method, called when the finger is lifted, simply check the “tap” flag: if the touch never moved from the original location, then “tap” is still YES, and you execute the code you want for handling a tap. Otherwise, handle the end of the dragging gesture. Without too much more work, you could also implement a tap and hold option: start a timer in -beginTracking. If the touch moves, cancel the timer at the same time you set the “tap” flag to NO. If the timer fires, then you know the user touched and held without moving. If desired, it would also be possible with a timer to set a short delay and listen for multiple taps, but then we’re getting into territory that might be good for an actual UIGestureRecognizer, or at least some different implementation that can properly make use of UITouch’s tapCount property.

All in all, I’m really happy with how this turned out. Once I thought about it for a minute, it was far easier than I anticipated. It’s a nice, simple implementation that can be stuck directly into the existing touch handling methods of UIControl/UIView, and it even lets you easily define what kind of “wiggle room” you want to allow before a tap becomes a drag, as well as easily set the time needed to count as a “tap and hold” if you go that route. With just a few lines of code and a couple flags checked in the right places, you can implement different actions for tap, drag, and tap and hold, plus various combinations of the three, on any UIControl or UIView subclass.

Time Flies When You’re Trying To Ship That App

Crunch Time

Wow. I can’t believe it’s already been four weeks since my last post. For one thing, that means I missed my iDevBlogADay slot last time around. For another thing, it means I’m less than 2 weeks away from my deadline for uploading my metronome app binary (part of why I missed the last post – super crunch mode!). But alas, it’s not going to happen. For anyone who may not know what I’m talking about, iTunes Connect allows you to begin the process of submitting an app – reserving the name, adding metadata, etc. – without actually uploading an app binary right away. However, to prevent name-squatters, once you start that process, you’ve got 120 days to submit. If you miss the deadline, your app is automatically deleted, and the name is back up for grabs for anybody but you! That’s right, you can never use that name for an app again. You may have noticed above when I mentioned “super crunch mode.” But wait, you might be thinking, isn’t that against what being indie as all about? Working for yourself, when you can, no forced week/month long crunches with no sleep and mandatory overtime to push out a product by some unrealistic deadline…

Not THAT Email!

…So, there I am innocently checking my inbox, when, bam! “You have not yet uploaded a binary for your app…If you do not upload a binary for your app by 14 October 2011 (Pacific Time), it will be deleted from iTunes Connect. The app name will then be available for another developer to use.” When I reserved my app name and began this whole process, I was well under way with what I thought would be the hardest part of the programming. Turns out I was right, it was the hardest part. So hard – or at least I’m still enough of a noob – that three months later I’m still messing with a few weird edge case bugs that, when they occur, render the controls basically unusable. Yeah, I get that email, and start to panic – OK, if I can get such and such a feature done in the next two days, then I’ll have enough to send out to testers, oh wait, still gotta find more testers. Then, all I’ll have to do is crank out an icon, finish the main screen design, decide which features to cut even though they were part of what would make my app unique, oh yeah, and there’s still that nasty bug lingering around…no problem, I can get it done in four weeks! And I tried. Well, I tried for about a week – putting off classwork, procrastinating on responsibilities for my actual (part-time) job, barely sleeping, having no time for my wife and friends…and then life caught up with me and I just HAD to step back and do some other stuff. And to be honest, I’m glad I did.

What To Do, What To Do…

That week, when I was trying to power through and crank out an app – a 1.0 version that would certainly be buggy and with subpar, rushed design – I hated it. There were a handful of thrilling moments, when major improvements came together quickly by sheer force and will-power and it looked like maybe I had a chance, but for the most part, it was awful. So, I’ve decided to let the deadline pass. Will I lose my app name? Maybe, although I had a few variations in mind already, so maybe it won’t be so bad to lose this particular one. There’s also a variety of supposedly valid ways to game the system and work around the deadline, but I won’t go into those. Google will help you out if you’re curious, but I’m just not sure how much stock to put into random, usually old forum postings of people saying they tried such and such, and it worked to save their desired name without actually releasing the app. I’m not going to get sucked into two more weeks of hell only to put out a crappy, unpolished product. That’s exactly what’s already out there (with some exceptions of course) and the reason I’m trying my hand at an already well-saturated market. I’m not going to completely throw away some of my desired and unique features because I jumped the gun on registering my app name. This is only my second major app project, so needless to say, I’ve still got a lot to learn about programming and time-management and estimation; I think it’s OK to cut myself some slack. I’m not going to get bogged down by the extreme stress a crazy two weeks like this would produce. What am I going to do? Get my app fully functional and thoroughly tested, and actually enjoy doing it, not to mention try to make the most of the potential 1.0 initial release sales bump with a quality product. I’m going to enjoy this beautiful fall weather and take my dog on walks like I did today. I’m going to go camping this weekend with great friends. I’m going to live life how I want to and allow space for some some hard work mixed with a little creativity and time to do its magic and hopefully lead me to a great app. And that’s how you do it indie style 🙂

Oh yeah, and I’m going to push that button over there and publish this post after midnight US central time. Oops, guessed I missed my iDevBlogADay deadline again. Oh well, at least Miguel won’t automatically delete my post and make me choose a new name!