Animating Polygon Shape Changes With CAShapeLayer in Swift and iOS

I am working on a project that will be animating polygon vector shapes. No raster images on a CAShapeLayer. In general, most of the references and examples related to CAShapeLayer are concentrated on animating stroke end points. That’s great for progress shapes where you are animating out the stroke, but what about simply going from one shape to another? How about in Swift?

Project and storyboard

Create a simple swift project. Place a view and a button on it. Set an IBOutlet for the view as shapeView, and an IBAction for the button. If you are impatient, you can download the demo project.

Create the objects

var shape1: UIBezierPath?
var shape2: UIBezierPath?
var isOpen: Bool = false
var shapeLayer = CAShapeLayer()

We’re going to animate from shape1 (a small polygon) to shape2 (a larger polygon), where the shapes are not the same.  The state between larger and smaller is kept by isOpen.

Start drawing

Let’s do some polygon shapes, and return a path.

func smallOpening() -> UIBezierPath {
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 35.5, y: 49.5))
bezierPath.addLine(to: CGPoint(x: 41.5, y: 42.5))
bezierPath.addLine(to: CGPoint(x: 47.5, y: 42.5))
bezierPath.addLine(to: CGPoint(x: 47.5, y: 42.5))
bezierPath.addLine(to: CGPoint(x: 59.5, y: 49.5))
bezierPath.addLine(to: CGPoint(x: 66.5, y: 57.5))
bezierPath.addLine(to: CGPoint(x: 59.5, y: 57.5))
bezierPath.addLine(to: CGPoint(x: 47.5, y: 63.5))
bezierPath.addLine(to: CGPoint(x: 35.5, y: 57.5))
bezierPath.addLine(to: CGPoint(x: 35.5, y: 49.5))
bezierPath.addLine(to: CGPoint(x: 35.5, y: 49.5))
bezierPath.lineWidth = 1
return bezierPath

func largeOpening() -> UIBezierPath {
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 8.5, y: 82.5))
bezierPath.addLine(to: CGPoint(x: 15.5, y: 51.5))
bezierPath.addLine(to: CGPoint(x: 32.5, y: 21.5))
bezierPath.addLine(to: CGPoint(x: 51.5, y: 11.5))
bezierPath.addLine(to: CGPoint(x: 69.5, y: 21.5))
bezierPath.addLine(to: CGPoint(x: 82.5, y: 41.5))
bezierPath.addLine(to: CGPoint(x: 82.5, y: 64.5))
bezierPath.addLine(to: CGPoint(x: 87.5, y: 82.5))
bezierPath.addLine(to: CGPoint(x: 51.5, y: 91.5))
bezierPath.addLine(to: CGPoint(x: 8.5, y: 82.5))
bezierPath.addLine(to: CGPoint(x: 8.5, y: 82.5))
bezierPath.addLine(to: CGPoint(x: 8.5, y: 82.5))
bezierPath.lineWidth = 1
return bezierPath

Start animating

Now that we have shapes, let’s animate them from one to the other using CABasicAnimation, and changing the whole path.

func openShape() {
let contractionAnimation = CABasicAnimation(keyPath: "path" )
contractionAnimation.fromValue = shape1?.cgPath
contractionAnimation.toValue = shape2?.cgPath
contractionAnimation.duration = 5.0
contractionAnimation.fillMode = kCAFillModeForwards
contractionAnimation.isRemovedOnCompletion = false
shapeLayer.add(contractionAnimation, forKey: "path" )
isOpen = true

func closeShape() {
let contractionAnimation = CABasicAnimation(keyPath: "path" )
contractionAnimation.fromValue = shape2?.cgPath
contractionAnimation.toValue = shape1?.cgPath
contractionAnimation.duration = 5.0
contractionAnimation.fillMode = kCAFillModeForwards
contractionAnimation.isRemovedOnCompletion = false
shapeLayer.add(contractionAnimation, forKey: "path" )
isOpen = false

We are animating from one path to the other, using the path key. We can change our path using fromValue and toValue. Set a duration. We want the animation to stay in place when it’s done, which is our isRemovedOnCompletion property. Set the state, so we know if we are open (bigger) or closed (smaller).

Load them up

Here we are creating our paths. A CAShapeLayer is all about the path, so we assign the smaller path to the it. Then we add  the CAShapeLayer to the view layer (which is a CALayer).

override func viewDidLoad() {
shape1 = smallOpening()
shape2 = largeOpening()
if let smallShape = shape1 {
shapeLayer.path = smallShape.cgPath
shapeLayer.fillColor = UIColor.gray.cgColor
shapeLayer.strokeColor =


Connect the button

Standard iOS stuff, let’s toggle the animations based on our isOpen state.

@IBAction func toggle(_ sender: Any) {
if isOpen {
} else {


This is a relatively small amount of code for this effect. Keep in mind that this is applied to a view. If you want to have views layered on top of one another to respect the shape edges, you’ll need to make the background color clear. Adding the sublayer will show your shape without the square of the view. Again, you can download the demo project.

Posted in iOS

Where In The World Have I Been?

I’ve really neglected my website. My choice, but I want to reverse that now. I’m going to try to start posting again. A lot of things have changed for me lately, as far as my career.

Demands On Time By Startups

The reasons for not posting are mainly related to my work, and my last two employers. The demands of a startup, and the crazy hours they often want, have some rather negative effects on things like blogs and public presentations. Both of these things which I have a lot of experience in, have become very rare. Given that I also like to take a lot of time to prepare a really good presentation, it becomes a time crunch. I had to pay the bills. Fortunately, that’s not an issue with my current employer, which is great!


First, I am no longer an Adobe User Group Manager. I turned those reigns over to someone else. Unfortunately, the group did not survive a year after. I was able to stay as an Adobe Community Professional for a while. I did two presentations I think, early on, but my time got heavily compromised, so I’m no longer officially affiliated with Adobe. I still love Adobe, but I just couldn’t set aside the time to meet my commitments. Having the content of my presentation materials online was a major reason for my blogging activity, so when that went away, so did the entries.

The Pleasure And Pain Of A Blog

I enjoy it when I’ve helped someone learn something, made a bunch of samples available, or published a fix to something truly obscure. I like giving back to the community. It’s fun to be quoted elsewhere. But…

I had a colleague of mine, who recently was let go from his job for criticizing Agile programming online. He didn’t mention any names or companies or people. He referenced other blog articles, and got fired. Naturally, this would have a chilling effect on what I’m going to say here, as historical record. While I have no doubt my current employer doesn’t care what I post, I can’t get it out of my head that someone would gladly disqualify me over a stupid blog post from the past. It’s a real thing.

What Did I Learn?

I have learned that I can get a job just fine. iOS is in demand, and that’s not changing anytime soon. I have a  better understanding of how I will fit or not fit, or how happy I would be, or how well I’d be utilized, better than I every have. This last time I made myself quietly available by word of mouth, and had two or three interviews (on phone or in person) every day for the next six days. That was exhausting. Things worked out great for me.

There’s a lot more, but, remember that part above about the pain?

What’s Next?

Predictions, advice, product reviews, and technical material. I have been pretty good at predicting what will stick and what won’t. There are some things I love, but recognize they are not ready yet. I’ve been helping many juniors try to get that first or second job. I need to do more to promote the products I love, and why I love them. And I’ll start posting presentations again, as I start doing those with more regularity.

Posted in Personal

Winter Effects in Photoshop CC

CC_PhotoshopA year ago, I presented on making it snow in a Photoshop video. I’ve found the original keynote and PDF for downloading. Enjoy!

Posted in Uncategorized

Let It Snow In Adobe After Effects CC

Adobe-After-Effects-CC-2014I’ll be presenting at the SLC Adobe Video Users Group in Draper on Wednesday, February 18th, at The Art Institute of Salt Lake City located at 121 W. Election Road Draper Utah. We’ll start at 6:30PM.

Feel free to download the source files and the keynote or you can download the PDF.

Posted in Uncategorized

iOS Tutorial: Selections in TableViews

This tutorial picks up where our last tutorial on TableView Basics left off. Now that we have one, it’s time to start editing, deleting and moving things around. Again, we’ll have our starter project and our completed project downloads.

First off, we can lose the button off the cell. Go to the storyboard and delete it. Delete the button code we had in the delegate method in RootViewController.m:

– (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPathSmilie: :(NSIndexPath *)indexPath


UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@”tvcItems”];

UILabel *lblName = (UILabel *)[cell viewWithTag:100];

[lblName setText:[maTheData objectAtIndex: [indexPath row]]];

return cell;


Table View Styles

We’re going to go into our storyboard and play with some attributes to explore what we can make the UITableView look like, and act. First, select the table view, and go to the Attributes Inspector. Change the table view style to Grouped. Run the project again. This looks a lot like Apple’s Settings app.

Apple’s documentation has some guides to read more about tables, including styles making indexed lists and creating sections. This is also available from Xcode->Organizer-Documentation.

Selecting Cells

In order to edit a cell, you first must be able to select a row and have it mean something. When we run our project and click a cell, it simply turns blue and stays that way. Change the selection attribute to Multiple Selection, and run again. Now as you select, they all go blue. This is certainly okay, but a lot of people prefer checkboxes to indicate selections, without anything going blue. To do this, we change the cell style, and deselect the cell. Really, no kidding.

For this we have another UITableView delegate method called didSelectRowAtIndexPath:

– (void)tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {

UITableViewCell *tvc = [tableView cellForRowAtIndexPath:indexPath];

if ([tvc accessoryType] == UITableViewCellAccessoryCheckmark) {

[tvc setAccessoryType:UITableViewCellAccessoryNone];

} else {

[tvc setAccessoryType:UITableViewCellAccessoryCheckmark];


[tvc setSelected:NO];


Run the project, and notice that we are toggling the checkmark, and deselecting, which turns off our blue.

Posted in Apple, iOS

What’s New in Photoshop Creative Cloud

Photoshop_CC_totem_5in_300ppiThe resource files for the SLC Adobe User Group are available for download.

We’ll cover most of the image editing enhancements, including blur gallery, smart sharpen, liquify, and up sampling. We’ll also show how to use CSS copy exports for use with Dreamweaver. We’ll cover a lot of the new light enhancements and image-based lighting (IBL) that have been added. Lastly, we’ll do some direct texture painting on a 3D model.

For information about the group and where to see the presentation, go to the site.

Posted in Adobe Tagged , ,

WebCode Workflow with Adobe Illustrator and Photoshop

webCodeIconImage256I’ve posted the content and slides from this week’s presentation on WebCode and Adobe tools.

As far as feedback from the group, there was considerable interest in the ability to convert PSDs to raster layers. I clearly didn’t give this feature the attention it deserved in my initial review. I’m a bit fixated on vectors right now. Many in my group are very much in the raster world, and they loved what WebCode was doing with PSD.

Why is this so cool?

If you consider that you can separately animate layers of raster content on a web page, it’s a very big deal. The support of Photoshop effects is shockingly good, far more than I reasonably expected. The exports from WebCode are outstanding by any measure. Some people like animating in Javascript, some like CSS animations. These exports make it very easy to do. Even the SVG export, with rasters, is easy to animate (although I would’t recommend ever scaling rasters up).

At $49.99, WebCode is worth every penny. It can be used by itself, and produce great stuff. That fact that it also plays so very well with Adobe products is miraculous. Love those PixelCut guys!

Posted in Adobe Tagged , , , ,

Software Review: PixelCut’s WebCode Is A Winner

webCodeIconImage256Pixel Cut has released a new tool called WebCode for creating your web images into code — web code, as in HTML, SVG, JavaScript+Canvas and CSS. Yes, very cool.

The Advantage of Vector Imaging on Your Website

Every webmaster and web designer knows that making great web images for sites, especially supporting retina screens (for iOS devices and Macs) or hi-res monitors is a major challenge. Vector is a great answer to breeding raster images on your site. Drawing vector through code is the same great answer. Getting this solution has required something like SVG (scaled vector graphic) generation with a tool like Adobe Illustrator or Inkscape. The more radical solution? A web programmer doing canvas drawing. That was it, and it can be intimidating. But solving the retina issue is a very big deal. It simply has to be done.

Enter PixelCut

Last year, software maker PixelCut made a name for itself with the spectacular PaintCode, which created Objective-C from vector tools or SVG import. I’ve used it on every single iOS project since its release. It’s that good.

I was pleasantly surprised to see the announcement of WebCode, which is a sister product doing the same thing, only the output code is a web variation of SVG, JavaScript+Canvas and CSS.

The question was: Does this product live up the the other? The answer is YES.

Familiar UI and Drawing Tools

The UI is the same familiar one, and looks identical. The way it handles attributes like colors, shadows, and gradients is the same. The vector drawing tools, booleans, use of dynamic frames, again, all the same. If you know PaintCode, you already know WebCode. The difference is in the output.


Output Code

Let’s face it, this is what you really care about. Does it do what it says it does, and is it usable and easy? Yes, it is. The sample files available on the site tell a great story, These are files of pure vector drawn goodness.

But I decided to do one of my favorite things, and pull in a complex vector tree SVG I’ve used in previous presentations. To my amazement, the SVG import (a simple drag-and-drop onto a blank canvas) worked! It’s an SVG, so I wanted to see what Canvas could do. The export was fantastic!

One note for those who use the HTML+CSS conversion, CSS does not support bezier curves. WebCode is very kind to let you know with the handy warnings drop-down just about the converted code.

The Samples

The sample downloads are wonderful. They are the basic drawings. However, the demo code that was added on the main page of the site is absolutely extraordinary. You must have a look at this stuff. It’s brilliant.

The Others

I’m not a big Inkscape fan, never will be. Yes, Adobe always has things going, I know, and I love that. They can all do SVG. But we have to look at here and now, and the pricing factor.


What can I say, they’ve done it again! If you are creating images for web, and they can be vector, like menu buttons, tabs, sliders, and icons, moving to vector is a major step forward in quality and performance. This is what HTML 5 is all about. (Sorry IE fans, you need more help than any of us can give you right now.)

WebCode is, without question, the best choice for easy JavaScript+Canvas and CSS drawing available today. At $49.99, WebCode is a bargain, and a real value I highly recommend it. You’d better buy one before the price goes up. It’s worth every penney.

I’m going to be presenting on this product soon, so stay tuned for more extensive info and samples.

Posted in CSS, HTML5, Mac, Technology

Adding Animations to WordPress with Adobe Edge Animate

ea_wpThis is really part one of more posts to come on Edge Animate and WordPress integration. Here is a link to the slides for tonight’s SLCAdobeUG meeting. It includes the vital links to get you up and running animating your WordPress site.

The first phase is to get animation going. The second phase will be to extend to responsive variations of animations. Stay tuned.


Posted in Adobe Tagged , , , ,

The Problem With iOS GitHub Component Examples Lately

blog-githubI’ve started to notice a disturbing trend lately, iOS Github examples that flat out don’t work nicely outside the example code.  Here are the typical problems:

  1. Non-ARC code
  2. No Storyboards
  3. Sample project megalomanic focus
  4. inaccuracies and generalities

Non-ARC code

Seriously. Some people are not paying attention. If you have some C code flying around, great, that makes sense. But a plain vanilla component that doesn’t, where the sample code or component does it’s own (usually flawed) memory management, is just asking for trouble. Stop it.

No Storyboards

Again, not paying attention to what Apple is recommending and promoting. If you’re going to share, most developers, especially new ones, will be doing storyboard projects nowadays. Figuring out out how to get something out of a storyboard is a lot easier than how to get it in.

Sample project megalomanic focus

I actually resent having to deep dive into a spaghetti AppDelegate. It is common that the example is complex hyjinx designed to avoid ARC and storyboards. Is it so hard to show a real world implementation? I don’t think so. To offending developers: How many posts do you need to yourself and on StackOverflow asking for some rational context? Your component will be a part of an app, not the focus. Take a look:

When a real world sample is posted, with obvious and useful implementation, it’s great. It also makes you look like a complete jerk. inaccuracies and generalities

If you’ve run into one of the previous three, you are very likely to get this as a bonus. My favorite is the commentary of how you would generally do this in storyboards, which are pretty much always completely wrong. Many also stress compiler settings to turn off ARC compiling for the sacred component class. People really read this stuff, and follow your directions, in sone vain hope that they can get it to work. Don’t write about stuff you haven’t actually done.

The Point

These things waste time. When I’m trying to help someone, and they give me a link to a hot mess of a component, it makes me very cranky. When I see something cool I may want to experiment with myself, and I see this stuff, I want to ask what their problem is.

I’ve reached the point where I don’t remotely respect anyone’s code in these samples. 90% of it is just crap. (Steve Jobs would not hesitate to agree) I just dive into the real meat of the class alone. From there I can get down to the real essence, and see if it’s even a good idea what’s going on or not. That’s fine for me, because I can figure it out. So…

Why am I blogging about this? The newbies are attracted to these components like a moth to the flame, and they are left hanging, and give up. What a shame. It shouldn’t be that way. Here’s my message:

If you’re going to post components, and encourage people to use them, have the courtesy to make them usable!


Posted in Apple, iOS Tagged