Here's a fully functional example of what (I believe) you're describing. I opened an empty single view project, deleted the view control in the storyboard, and simply created a UITableViewController and set its class to the class of a UITableViewController subclass i've created below.
There's nothing added to the header file, so i've excluded it
#import "weeeTables.h"
@interface weeeTables ()
@property (nonatomic, strong) NSMutableSet *shownIndexes;
@property (nonatomic, assign) CATransform3D initialTransform;
@end
The shownIndexes will contain in indexes of the views already displayed, so we don't repeat the animation scrolling back up. The initialTransform property is the transform for the initial state of the cell (where you want it before it comes on screen)
@implementation weeeTables
- (void)viewDidLoad {
[super viewDidLoad];
CGFloat rotationAngleDegrees = -30;
CGFloat rotationAngleRadians = rotationAngleDegrees * (M_PI/180);
CGPoint offsetPositioning = CGPointMake(-20, -20.0);
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, rotationAngleRadians, -50.0, 0.0, 1.0);
transform = CATransform3DTranslate(transform, offsetPositioning.x, offsetPositioning.y, -50.0);
_initialTransform = transform;
_shownIndexes = [NSMutableSet set];
}
in ViewDidLoad, we setup the values for the initial transform, I played with the values a bit, and encourage you to do the same to get the effect you're looking for, but the cells animate in from the lower left corner currently.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 385;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"weeCell" forIndexPath:indexPath];
return cell;
}
everything in the block above is pretty typical for a UITableViewController subclass, and has no particular relevance to adding the animation, I just set some static numbers to add plenty of cells to scroll through, the only unique value here is the cell identifier, which as you can see has a very carefully thought out name.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (![self.shownIndexes containsObject:indexPath]) {
[self.shownIndexes addObject:indexPath];
UIView *weeeeCell = [cell contentView];
weeeeCell.layer.transform = self.initialTransform;
weeeeCell.layer.opacity = 0.8;
[UIView animateWithDuration:.65 delay:0.0 usingSpringWithDamping:.85 initialSpringVelocity:.8 options:0 animations:^{
weeeeCell.layer.transform = CATransform3DIdentity;
weeeeCell.layer.opacity = 1;
} completion:^(BOOL finished) {}];
}
}
@end
Here's the guy that really puts it all together, first we check to see if the cell we're about to display is already in the list of shownIndexes, if it isn't we add it, then create a local variable for this current cells content view.
Then set the transform on that contentView to our initial transform (that we setup in ViewDidLoad). That moves the cell off to our starting position before it's visible to the user, then we animate that transform back to the identity transform. I've got opacity in there too, just for hell of it.
Hope it helps!