Example from Mac OS X:
[[aView animator] setFrame:NSMakeRect(100.0,100.0,300.0,300.0)];
I have tried something similar in UIKit, but it seems the animator method is not there for UIView. So there's no "implicit" animation?
Example from Mac OS X:
[[aView animator] setFrame:NSMakeRect(100.0,100.0,300.0,300.0)];
I have tried something similar in UIKit, but it seems the animator method is not there for UIView. So there's no "implicit" animation?
The iPhone supports implicit animation, though it does not use an animator object, it is built directly into UIView. Try this instead:
[UIView beginAnimations:nil context:nil];
[aView setFrame:NSMakeRect(100.0,100.0,300.0,300.0)];
[UIView commitAnimations];
The exact details are documented here.
Every view is always layer backed as well, so you don;t have to turn on layers in order to get a layer for explicit animation.
Turns out iPhone OS does indeed support implicit animations on CALayer as defined in the Core Animation Programming Guide from Apple. On Mac OS X, a layer becomes animatable when it backs an NSView by setting:
[view setWantsLayer:YES];
On iPhone OS, simply set the layer delegate to the UIViewController-derived class that hosts the UIView-derived object you would like to animate. For example, if you have a property defined for a UILabel called label, inside of the UIViewController-derived class that hosts it, the code would look something like this (an example of an event handler for a UIButton Touch Up Inside event):
-(void) buttonPressedToAnimateTheLabel:(id)sender
{
CALayer *labelLayer = self.label.layer;
labelLayer.delegate = self;
layer.position = CGPointMake(labelLayer.position.x, labelLayer.position.y + 50);
}
The label will then animate in the exact same manner as it would on Mac OS X just by changing the position.
Some notes about this:
it is definitely the UIViewController that is the delegate, not the UIView. Making a UIView the delegate causes the app to blow up.
the delegate needs to be set in a method called after the UIViewController-derived class has completely finished loading, i.e. in an event handler for a control hosted by the class. I tried adding it in initWithNibName:bundle:, awakeFromNib, viewDidLoad, and viewWillAppear:animated and it did not work. Setting the delegate in the first two methods caused the label not to animate; it just changed positions immediately. Adding it in the last two caused the label to disappear altogether.
after the delegate is set once in an event handler, it will be good for the remainder of the lifetime of the UIViewController-derived class. Changing the layer properties in other event handlers will cause them to animate without setting the delegate for the layer again.
when the UIViewController-derived class loses focus, the delegate must be set to nil in the viewWillDisappear:animated method, or else the application will blow up
There must be some place to set the delegate one time only so it isn't set multiple times as a result of a event handler being called, but I have yet to find that place. At least it works this way and setting it multiple times as a result of the event handler being called multiple times seems harmless enough.
It would certainly be nice if this was all documented in the Core Animation Programming Guide. I spent days trying to figure this out! Hope this saves all the trouble of hunting it down!