AS3 to Cocoa Touch: MovieClip vs UIView
UIView vs Movieclip.
It’s true that the UIView object has comparisons with the Movieclip object in actionscript.
But not everything is the same. I’m going to discuss a couple of examples that you would do with a movieclip and show you how to can achieve the same result in objective-c with the UIView object.
But first a couple of statements about the UIView / Movieclip object:
| Movieclip | Question | UIView |
| ✓ | The object is a container for view/display objects | ✓ |
| ✓ | You can draw into the view/display object | ✓ |
| ✓ | You can animate the object directly | ✓ |
| ✓ | Accessing view through id | ✓ |
Containing childs :
//Actionscript 3 for( var i : int = 0 ; i < 10 ; i ++ ){ var rect : Rectangle = new Rectangle(); //Custom object rect.x = 50*Math.floor(i%4); rect.y = 90*Math.floor(i/4); addChild(rect); } trace(numChildren); //result: 10
//Objective-C for(int i = 0; i < 10 ; i++){ Rectangle *rect = [[Rectangle alloc] initWithFrame:CGRectMake(0,0,40,80)]; //Custom Object rect.transform = CGAffineTransformMakeTranslation(50*floor(i%4), 90*floor(i/4)); [window addSubview:rect]; //See that your window variable is accessible [rect release]; } NSLog(@"%i",[[window subviews] count]); //result: 10
You just allocate your object and initiate it with the initWithFrame: function. You pass it the size and position you want in our case x,y = 0 the width is 40 and the height 80 in our case.
since you can’t directly acces the frame X and Y values ( except if you pass a new CGRect to the frame property)
there is a big difference with UIView and Movieclip
With UIView you have to specify a canvas when you init the object
a Movieclip will autoresize to the content inside, unless you define the width and height
with the use of a UIView you have 2 important property’s , Frame & Bounds ( understanding frame and bounds )
//rect.frame.origin.x = 100.0f; <- will give an error (invalid lvalue in assignment) CGRect frame = rect.frame; frame.origin = CGPointMake(100,0); rect.frame = frame;
but I’m in favor to use the transform property and pass it an Matrix Translation with the CGAffineTransformMakeTranslation function which returns an matrix translation structure.
I pass it the x and y values I want (in this case I’m iterating my x and y values so it will look like the picture below)
don’t forget to release your object If your not going to use it anymore
and our window subviews count is 10

Comparison iphone as3
on the left flash in the browser on the right the iphone (looks exactly the same)
Drawing into a view/display object:
//Actionscript 3 public function Rectangle() { super(); graphics.beginFill(0xFF0000); graphics.drawRect(0,0,40,80); graphics.endFill(); }
Objective-C - (void)drawRect:(CGRect)rect { // Drawing code CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0); CGContextFillRect(context, rect); }
If you make a view object in xcode there will be a function created for you called drawRect:
that’s the function where you mostly want to put your code for drawing.
the first thing that you got to do is get the graphics context (in a movieclip that’s just a property but in objective c you can get the graphics context with a simple function)
you define which rgb color you want to use for that context and you fill that rect using the CGContextFillRect passing it the context + the frame you want to draw it in.
the drawRect: function is automatically called on initialization and the rect that is passed is the frame property. Since our frame-size is 40×80 we just pas it the rect (you could define your own rect).
if you want to redraw don’t ever call the drawRect: method directly! (EVER..)
use the setNeedsDisplay or setNeedsDisplayInRect: function.
Animating your view/display object:
you can animate your view in 2 different ways, using the animation methods provided by the UIView or changing the properties using a timer.
Which would be the same as using the Tween class or changing the property values in an onenterframe event.
//Actionscript 3 //Append this code to the previous function var rectAnim1 : Rectangle = new Rectangle(); rectAnim1.y = 90*4; rectAnim1.x = 100; rectAnim1.addEventListener(Event.ENTER_FRAME, animateHandler); addChild(rectAnim1); var rectAnim2 : Rectangle = new Rectangle(); rectAnim2.y = 90*4; rectAnim2.x = 200; addChild(rectAnim2); TweenLite.to(rectAnim2, 5, {rotation:180,ease:Expo.easeInOut}); //end private function animateHandler( e : Event ) : void { Rectangle(e.target).rotation = Rectangle(e.target).rotation+1; }
//Objective-C //Append this code to the previous function Rectangle *rectAnim1 = [[Rectangle alloc] initWithFrame:CGRectMake(100,90*4,40,80)]; //Custom Object [window addSubview:rectAnim1]; rectAnim1.transform = CGAffineTransformMakeRotation(0); [UIView beginAnimations:@"rotate" context:nil]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationDuration:5]; rectAnim1.transform = CGAffineTransformMakeRotation(3.14); [UIView commitAnimations]; rectAnim2 = [[Rectangle alloc] initWithFrame:CGRectMake(200,90*4,40,80)]; //Custom Object (added to you interface so you can acces it from other functions) [window addSubview:rectAnim2]; [NSTimer scheduledTimerWithTimeInterval:0.033f target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES]; //end - (void) handleTimer:(NSTimer *)timer { angle += 0.03; rectAnim2.transform = CGAffineTransformMakeRotation(angle); }
So for the first animation were going to use the animation methods provided by the UIView we define a beginning and we give it a name. we define the curve and the duration. Than we define all our transformation we want to make happen. And we commit the animations (which means that they will instantly start playing.
For the other example we use a Timer, we schedule a timer that will tick every 0.033seconds we define the method that we want to be called every tick with a selector en we define a repeat so it will repeat endlessly
In the method handleTimer we just going to rotate by adding 0.03 to the currentAngle
Accessing view through id:
//Actionscript 3 //you need to name your movieclip (with a number) //so add this line of code into your for loop rect.name = String(i); //end trace(this.getChildAt(3)); trace(this.getChildByName("3")); //returns the movieclip with name “3”
//Objective-C //you need to tag our views (with a number) //so add this line of code into your for loop rect.tag = i; //end NSLog(@"%@",[window viewWithTag:3]); //returns the view with tag “3”
There are a lot more comparisons like they both have the alpha property, you can insert views at a certain index, observing changes, and a lot more. I just wanted to point out a couple of practical comparisons between the 2 languages.
Hey thanks for putting this up, I’m making a transition from AS3 to Objective C, and this helps a lot.
Hey, great blog! The transition of an ecma script language to a obj-c is pretty nasty, and I’ve been fighting various parts of it for the last couple months. I think though, that Sprite is a better analog for the UIView class; being that they’ve both very lightweight classes that are meant to be subclassed. The only advantage in Movieclip in the analogy that I can see is that you can design it’s children directly ( in the ide ), which you can do with UIView but not with Sprite. But even then, there are some easy ways to design directly into Sprite subclasses with the ide.
Also, you were looking for a good xml parsing engine that will work in cocoa touch. Try TouchXML. It doesn’t have the handy e4x syntax, but it does have good XPath support.
Hi,
your absolutely right!
I think Sprite would indeed be a better analog for the UIView.
But the term is more widely know amongst the actionscript developers.
I debated but eventually I figured MovieClip is quite the same but has a lot more “name” than sprite does.
Heya Andy, really quick question: have you found any equivalents to the AS3 tweening engines in objective C? I’m really dependent these days on being able to do elastic tweens and quadratic ease-outs!
Oh snap, I’m so sorry Andy. I was reading the shortened article on the front page and clicked “add comment” and then was taken to the bottom and didn’t realise I was… asking a question you’ve already answered in your post. I feel dirty.
You can do tweens with with the animation library provided as i showed you in the example
there is a setter setAnimationCurve where you can set UIViewAnimationCurve
in fact here are all the property’s you can set
* + beginAnimations:context:
* + commitAnimations
* + setAnimationStartDate:
* + setAnimationsEnabled:
* + setAnimationDelegate:
* + setAnimationWillStartSelector:
* + setAnimationDidStopSelector:
* + setAnimationDuration:
* + setAnimationDelay:
* + setAnimationCurve:
* + setAnimationRepeatCount:
* + setAnimationRepeatAutoreverses:
* + setAnimationBeginsFromCurrentState:
* + setAnimationTransition:forView:cache:
* + areAnimationsEnabled
i didn’t need an external ( i don’t know if there exists one .. maybe i’m not aware of .. if you do find one let me know
) library to do my tweening because the internal library was pretty sufficient for me.
i hope this can help you
(That said, there’s only some very basic easing in the library, is there anything to cover more complex moves?)
Oh I’m really making a tit of myself now. Thanks so much boss!