When Apple revealed iOS 7 at this year’s WWDC, it was obvious that the new app icons had a more rounded rectangular shape. I was happy to see the improvement, because the old shape had an awkward transition between the rounded corners and the straight edges. With this new shape, it’s almost as if someone at Apple decided to finish the job and polish the corners with some high grit sandpaper.
I’ve spent the last couple of months updating my apps to take advantage of iOS 7, and during that time, I’ve had to recreate many graphical assets in Photoshop. Early on, I noticed that the rounded rectangles I was making in Photoshop didn’t match the screenshots of my app running on iOS 7. Further investigation revealed that the underlying functions that create rounded rectangles in iOS 7 (like [UIBezierPath bezierPathWithRoundedRect:cornerRadius:]) were all-of-the-sudden creating these new, smoother corners.
So, I ran the output of the UIBezierPath method through the vector processing code in Halftone 2, and I ended up with an Adobe Illustrator diagram of its construction. Turns out, I wasn’t the first person to use this approach, and Manfred Schwind has an excellent post on the subject of introspecting a CGPath to arrive at the same conclusion.
I quickly tired of exporting paths through Halftone 2 to Illustrator and then to Photoshop, and I couldn’t find any available tools or plug-ins to generate the new curves for me. Long-time readers of my blog are familiar with my Illustrator plug-ins—and believe me—I was tempted to start there. But, I needed these curves to be pixel-aligned in Photoshop, and this sounded like a great excuse to write my first Photoshop plug-in. I fully expected to download the SDK and start writing some C++, but I soon discovered that I could accomplish everything I needed with a script.
The first thing I had to do was reverse-engineer the logic in [UIBezierPath bezierPathWithRoundedRect:cornerRadius:]. I exported many rounded rectangles, each with a different corner radius, and compared the anchor and control points across all of the CGPaths. With this data, I was able to determine the relative location of each coordinate and create my own Objective-C class that generates the same output as UIBezierPath (accurate to 4 or 5 decimal places). Curiously, my code actually runs about 35% faster than UIBezierPath. Go figure. It’s also important to note that I’ve updated the values based on the final release of iOS 7.
Finally, I ported my Bezier class to a Photoshop script, added a simple dialog, and I’ve been using it to update my image assets ever since.
The script was written and tested with Photoshop CC on Mac and PC (32- and 64-bit), but it may work on earlier versions too (there’s no harm in trying it). I’ve heard a report from one user that it works just fine with Photoshop CS5. If you’re able to successfully use it with an earlier version, please leave a comment.
I’ve added a permanent page to host the script, and any future updates will be available there:
Enjoy!
Leave a Reply