PrEV
Thoughts from a NeXTStep Guy on Cocoa Development

Virgin Galactic

Jan 23, 2008 by Bill Dudney

So way back in the day when I worked at NASA (my degree is in AeroSpace Engr from Texas A&M) one of the projects I was involved in was the space suits for Reagan's space station. That was supposed to be assembled from K'enx type things and they needed new suits to give the astronauts more time in space (among other things). Anyway as part of that work I got to go flying in what is affectionately known at NASA as the Vomit Comet.

Anyway I noticed that Virgin Galactic announced their space ship today.

Step 1

At a cost of about $200,000 USD for 4 minutes of Zero-G (or around $830/second) it reminded me of the good ol' Vomit Comet. Which also reminded me of Zero G Corp. While its not orbital its a bit more cost effective at around $4000 (with 7 to 8 minutes of zero g or around $8.30/second). So while the Virgin Galactic flight might be cool, for the working class there is always Zero G Corp.

Permalink     2 Comments - Add Yours

OpenTV a way to deliver training? Would you buy?

Jan 22, 2008 by Bill Dudney

Now that I'm getting close to finishing the book one of the things I'm thinking about is offering a Core Animation training class. I've been brain-storming over ideas about how to deliver that training. The traditional means is reasonable I think and I'll probably do a class through my friends at About Objects but I'd also like to do something innovative with online delivery.

Lynda.com has one approach that I think I like. For those not familiar you pay a subscription to get access to tons and tons of great training. They have lots of good samples and stuff for you to grab to get a feel for if you like the content or not so you don't get left feeling like you made a mistake. You know what you are getting going into it. A decent model. I don't know though how much I'd make from providing them additional content.

Enter OpenTV Network. I like the model and as a content provider getting 85% of the revenue is a great deal. [Philip Hodgetts has an interesting write up of what he thinks of this (I think he is the founder of Open TV) new distribution and a pricing model.] The basic idea is that you open a 'tab' with OpenTV and when you spend a preset amount (say $15 or something) or over a preset time limit (once a month) your tab would be settled with your credit card (like a bar tab). So when you buy a 5 minute video for $0.25 you won't see a single twenty-five cent charge on your credit car. Instead all the videos you buy would show up as one charge.

So the question is, what do you think? If I did a 3 to 5 minute video of how to do something with Core Animation would you pay a quarter for it? Would you subscribe to it at 6 to 8 episodes a month? Is it worth it to you to have a video podcast type format to learn CA with. Doing simple one off stuff like my quick and simple intro to CA here are one thing. But doing a consistent video podcast is another, it takes a lot more commitment and investment (well I really want a new mac pro anyway, but this would be a great excuse).

Permalink     2 Comments - Add Yours

Front Row like Menus with Core Animation Layers

Jan 11, 2008 by Bill Dudney

A couple of weeks ago someone on the Cocoa-Dev list was asking about making a menu item like the one in Front Row. There were several suggestions and many of them good but none that I thought 'oh that is it'. So I figured I'd post mine here on my blog.

While its not perfect it does show some of the tricks necessary to mold Core Animation to your will.

Before we get started lets do a quick list of steps.

  • Create a 'menu' layer - assumed and not discussed
  • Put the 'menu' layer into a scrolling layer - assumed and not discussed
  • Add 'menu item' layers for each menu item - assumed and not discussed
  • For the selected item:
    • Add a 'bloom' filter to the arrow character
    • Add a blue shadow
    • Add the 'reflection' highlight to the top
  • Live Happily Ever After.

We are going to skip over the scrolling layer and the menu layer in this post. I'll post again about scrolling layers later.

Here is the code snipit that does all the 'highlight' steps in one place. We will go into the detail in the remainder of this post.

  [scrollLayer setValue:[NSNumber numberWithInteger:value] forKey:@"selectedItem"];

  // get the newly selected item

  CALayer *itemLayer = [[menuLayer sublayers] objectAtIndex:value];

  // make sure its scrolled to visible

  [itemLayer scrollRectToVisible:itemLayer.bounds];

  // -- apply the selection features --

  // apply the bloom effect

  CALayer *arrowLayer = [[itemLayer sublayers] objectAtIndex:1];

  [arrowLayer setFilters:[NSArray arrayWithObject:[self bloomArrowEffect]]];

  // set the shadow to visible

  itemLayer.shadowOpacity = 0.85f;

  // add the highlight layer

  [itemLayer insertSublayer:[self highlightLayer] atIndex:0];

Add Bloom Filter

We create the bloom effect with a Core Image bloom filter like this;

- (CIFilter *)bloomArrowEffect {

  if(nil == bloomArrowEffect) {

    bloomArrowEffect = 

    [CIFilter filterWithName:@"CIBloom" 

               keysAndValues:kCIInputRadiusKey, [NSNumber numberWithFloat:5.0f], 

     kCIInputIntensityKey, [NSNumber numberWithFloat:1.0f], nil];

  }

  return bloomArrowEffect;

}

Then the filter is added to the 'arrowLayer' like this;

  CALayer *arrowLayer = [[itemLayer sublayers] objectAtIndex:1];

  [arrowLayer setFilters:[NSArray arrayWithObject:[self bloomArrowEffect]]];

Adding CI effect is one of the coolest eye-candy things that we can do with Core Animation, we could even animate the bloom (i'm not here but you could if you wanted to, if there is enough interest I'd be glad to add it to this example).

Now we have our arrow layer being highlighted its time to move on to the shadow.

Add Blue Shadow

During the initialization of the menu item layers we add the shadow like this;

    layer.cornerRadius = 2.0f;

    layer.shadowRadius = 15.0f;

    layer.shadowOffset = CGSizeMake(0.0f, 0.0f);

    layer.shadowColor = [self blue];

    layer.backgroundColor = [self black];

We specifically set the offset to (0,0) because we want the shadow to come out from under the whole layer, if we set the offset to something it would not be the effect we are looking for, when you are playing with the code make sure to change this to see how it looks when you set the offset.

We set the background color to get the layer to cast a shadow. Remember that the shadow stuff in CA works a lot like the Transparency Layer stuff does in quartz. The drawing done in your layer has the shadow applied to it. If there is no drawing there is now shadow. Setting the background ensures that there is drawing. If you leave out the background color you get shadow only under the text layers, which looks cool too but is not what Front Row looks like. Since we are shooting for Front Row I've done things this way.

Now as the selection changes all we do is set the shadow's transparency to 0.85 (we set it to zero to make it invisible, check out the code for unselectCurrentSelection in the project download).

  itemLayer.shadowOpacity = 0.85f;

Now lets look at the highlight layer.

Add Reflection Highlight

Setting the highlight layer is easy, all we do is place it in the zeroth spot of our sublayers array, like this;

  [itemLayer insertSublayer:[self highlightLayer] atIndex:0];

The real trick is in setting up the highlight layer. Lets look at that code now. While it looks like a lot the code is really simple.

- (CALayer *)highlightLayer {

  if(nil == highlightLayer) {

    highlightLayer = [CALayer layer];

    highlightLayer.masksToBounds = YES;

    highlightLayer.layoutManager = [CAConstraintLayoutManager layoutManager];

    [highlightLayer addConstraint:

     [CAConstraint constraintWithAttribute:kCAConstraintWidth

                                relativeTo:@"superlayer" 

                                 attribute:kCAConstraintWidth]];

    [highlightLayer addConstraint:

     [CAConstraint constraintWithAttribute:kCAConstraintHeight

                                relativeTo:@"superlayer" 

                                 attribute:kCAConstraintHeight]];

    [highlightLayer addConstraint:

     [CAConstraint constraintWithAttribute:kCAConstraintMinX

                                relativeTo:@"superlayer" 

                                 attribute:kCAConstraintMinX]];

    [highlightLayer addConstraint:

     [CAConstraint constraintWithAttribute:kCAConstraintMinY

                                relativeTo:@"superlayer" 

                                 attribute:kCAConstraintMinY]];

    // highlight at the top of the selection layer

    CALayer *layer = [CALayer layer];

    layer.backgroundColor = [self white];

    layer.opacity = 0.25f;

    layer.cornerRadius = 6.0f;

    [layer addConstraint:

     [CAConstraint constraintWithAttribute:kCAConstraintWidth

                                relativeTo:@"superlayer" 

                                 attribute:kCAConstraintWidth]];

    [layer addConstraint:

     [CAConstraint constraintWithAttribute:kCAConstraintHeight

                                relativeTo:@"superlayer" 

                                 attribute:kCAConstraintHeight]];

    [layer addConstraint:

     [CAConstraint constraintWithAttribute:kCAConstraintMinX

                                relativeTo:@"superlayer" 

                                 attribute:kCAConstraintMinX]];

    [layer addConstraint:

     [CAConstraint constraintWithAttribute:kCAConstraintMinY

                                relativeTo:@"superlayer" 

                                 attribute:kCAConstraintMidY offset:self.offset/2.0f]];

    [highlightLayer addSublayer:layer];

  }

  return highlightLayer;

}

The big picture is that we are setting up two layers, one as a child one as a parent. The highlightLayer has a single child with a backgroundColor of white and an opacity of 0.25. The child also uses rounded corners (radius set to 6). The highlightLayer is set to clip its sublayers (via the masksToBounds property being set to YES, remember that unlike views layers do not clip their sublayers by default). The rest of the code is just setting up constraints as to the way the layers sit in their superlayers.

And finally here are some diagrams of the layer layout. The first one shows the menu layer's layout. The second shows the selected layer and its parts.

Step 1
Step 1

And now the whole UI showing the 'Podcasts' item highlighted.

Front Row Menu

As I said earlier this is far from perfect but I like it better than the alternatives I saw posted. Any feed back is as always greatly appreciated. I have posted the code here for thoes that would like to play around with it. And there is much more about this example (and lots of others) in the Core Animation Book which will be entering Beta in the next week or two.

Permalink     11 Comments - Add Yours

Beta here we come!

Jan 11, 2008 by Bill Dudney

I've been making great progress on the book. I have submitted chapters 2 to 7 for editorial review and 1, 2, 3 and 4 are very close to being ready for beta, so everyone that has signed up to help review (thanks again BTW!) you should be hearing something in the next week or so.

Some things that would be extremely helpful as you read the book and offer criticism.

  • Does the chapter/book flow, do the ideas logically progress from one to the next for you?
  • Is the pace too fast or too slow?
  • Are the assumptions made to broad or too narrow?
  • Grammar and Spelling

Despite our best efforts to make sure all this stuff is spot on its not possible to catch everything. And besides writing a book is all too often like the process described in this interview with Garrison Keillor in which he sums up writing as

Writing is revising. You just keep messing around, cutting the dead wood, forcing the plants to bloom, until whomever you're writing the piece for gets exasperated and then you send it to them.

And while Daniel is fairly hard to exasperate I am exceedingly good at it so your feedback is critical!

Permalink     2 Comments - Add Yours

Count And Capture...

Jan 07, 2008 by Bill Dudney

A friend of mine has had great success building iPhone webapps. He has delivered two run away 'best of' apps that remained in the top 10 for weeks at a time, the first was Tic Tac Touch and the second was Connect4. About 2 or so weeks ago while waiting for National Treasure 2 to start my wife and I were sitting eating our popcorn and chatting when we noticed the person in front of us was playing Connect4 on their iPhone. That was a cool moment, I called Mike on the phone to let him know. Two days later I started getting questions from my lovely wife about JavaScript and HTML.

The fruit of the encounter in the theater and our long discussions since then is a new game for the iPhone. iKala is born. Hope you enjoy playing as much as we enjoyed making it.

Permalink     Add A Comment