What is the initial x coordinate of a UITableViewCell? - ios

In a UITableViewController, this function logs into the console the x coordinate of the tableview cells
- (void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath
{
//1. Setup the CATransform3D structure
CATransform3D rotation;
rotation = CATransform3DMakeRotation( (45.0*M_PI)/180, 0.0, 0.7, 0.4);
rotation.m34 = 1.0/ -600;
//2. Define the initial state (Before the animation)
cell.layer.shadowColor = [[UIColor blackColor]CGColor];
cell.layer.shadowOffset = CGSizeMake(10, 10);
cell.alpha = 0;
cell.layer.transform = rotation;
cell.layer.anchorPoint = CGPointMake(0, 0.5);
//4. Define the final state (After the animation) and commit the animation
[UIView beginAnimations:#"rotation" context:NULL];
[UIView setAnimationDuration:0.3];
cell.layer.transform = CATransform3DIdentity;
cell.alpha = 1;
cell.layer.shadowOffset = CGSizeMake(0, 0);
[UIView commitAnimations];
NSLog(#"X%d= %d,Y%d=%d",(int)indexPath.row ,(int)cell.layer.position.x,(int)indexPath.row,(int)cell.layer.position.y);
}
it logs for the cells that are initially displayed (cell 0 to 12)
X0= 160,Y0=25
X1= 160,Y1=75
X2= 160,Y2=125
X3= 160,Y3=175
X4= 160,Y4=225
X5= 160,Y5=275
X6= 160,Y6=325
X7= 160,Y7=375
X8= 160,Y8=425
X9= 160,Y9=475
X10= 160,Y10=525
X11= 160,Y11=575
X12= 160,Y12=625
But after scrolling the tableview, it logs
X13= 0,Y13=675
X14= 0,Y14=725
X15= 0,Y15=775
X16= 0,Y16=825
and only cell 13's view is offset by 160 in the simulator
This could be fixed by adding to the previous method
if(cell.layer.position.x != 0){
cell.layer.position = CGPointMake(0, cell.layer.position.y);
}
What I am asking is why initially the x coordinate = 160 ???

The position of a layer denotes its center position, and not the top-left corner. you changed that behaviour through manipulation of the anchorPoint property. Insert the following line after the line that contains anchorPoint:
cell.layer.position = CGPointMake(0, cell.layer.position.y);
Changing the anchorPoint also changes the frame. To keep the frame the same, you have to do the opposite movement with the position property.
(To get the position of the top-left corner, you would use cell.frame.origin instead.)
See also: CALayer reference

Related

UIView move up & down

currently I am moving uiviews from left to right on the swipe gesture of down how can I change transition to up and down
-(void)slideToRightWithGestureRecognizer:(UISwipeGestureRecognizer *)gestureRecognizer
{
[UIView animateWithDuration:0.5 animations:^{
self.calendar.frame = CGRectOffset(self.calendar.frame, 320.0, 0.0);
self.secondCalender.frame = CGRectOffset(self.secondCalender.frame, 320.0, 0.0);
}];
}
The last parameter in CGRectOffset is the vertical offset. Pass a non-zero value in that and you'll move the view up/down.
/* Offset `rect' by `(dx, dy)'. */
CGRect CGRectOffset(CGRect rect, CGFloat dx, CGFloat dy)

Set anchor point in UICollectionViewLayoutAttributes

I want to perform transform animation in UICollectionViewLayout. Well that is achieved easily but I can't find way to set the anchorPoint of UICollectionViewLayoutAttributes. I want to perform door opening and closing animation while collection view item is inserted
-(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath{
UICollectionViewLayoutAttributes *attributes = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
attributes.alpha = 1.0;
CGFloat progress = 0.0;
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0/500.0;
CGFloat angle = (1 - progress) * M_PI_2;
transform = CATransform3DRotate(transform, angle, 0, 1, 0 );
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:itemIndexPath];
cell.hidden = YES;
attributes.transform3D = transform;
return attributes;
}
There doesn't seem to be an anchorPoint attribute in UICollectionViewLayoutAttributes, so you'll have to subclass it, add a property for anchorPoint and use the applyLayoutAttributes on UICollectionViewCell to set the anchorPoint value on the cell.

UITableViewCell animation breaks UITableView touch detection and scrolling

I was trying to achieve similar to google+ animation on showing new UITableViewCells when they appear for the first time.
This is what I'm doing:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if([[self serverFetchControllerForTableView:tableView] hasDataAtIndexPath:indexPath])
{
if (![[self shownIndexesForTableView:tableView] containsObject:indexPath]) {
[[self shownIndexesForTableView:tableView] addObject:indexPath];
UIView* view = [cell contentView];
view.layer.transform = self.initialTransformation;
view.layer.opacity = 0.0;
[UIView animateWithDuration:ANIMATION_CELL_APPEARANCE_TIME animations:^{
view.layer.transform = CATransform3DIdentity;
view.layer.opacity = 1;
}];
}
}
}
//initial transformation looks like that
CGFloat rotationAngleRadians = ANIMATION_CELL_APPEARANCE_ANGLE_DEG * (M_PI/180);
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, rotationAngleRadians, 1.0, 0.0, 1.0);
transform = CATransform3DTranslate(transform, ANIMATION_CELL_APPEARANCE_X, ANIMATION_CELL_APPEARANCE_Y, 0.0);
self.initialTransformation = transform;
Everything works in terms of visuals, but while those cells are appearing, I'm losing complete control of UITableView scrolling - I cannot touch cells, stop scrolling or select any of them, until animation is finished.
Does anyone have any suggestion what I can do better here to fix that problem ?
Same problem can be found here:
http://www.raywenderlich.com/49311/advanced-table-view-animations-tutorial-drop-in-cards
Try putting time to 3.0seconds in TipInCellAnimator any for 3.0 control is lost completely.
This is the normal behavior for animations using one of the animateWithDuration... methods. If you want user interaction during the animation, try using
animateWithDuration:delay:options:animations:completion: and passing UIViewAnimationOptionAllowUserInteraction as the option. I don't know what that might do to your animation, but it should allow user interaction.

UITableViewCell Position Off After Animation

I have an animation going on in -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *). The cells essentially rotate in (code below). They do this every time they load onto the screen. The cells that rotate in initially (that is, the ones visible on screen at the beginning) look like the "Before" snapshot below. Small (normal) indentation. After scrolling down or around, new cells are animated onto the screen, but they look like the "After" shot. They're off by a few pixels. Once I scroll up again, the upper cells are reloaded and also have the larger indentation. All of which would be fine, except depending on scroll behavior, sometimes some cells are indented and others aren't and it looks awful. I tried resetting the indent property of UITableViewCell but it didn't do anything. Any ideas what could cause this odd behavior? Perhaps a property I'm not aware of I should be setting? Thanks!
Before:
After:
//Animation Code Borrowed From http://www.thinkandbuild.it/animating-uitableview-cells/
//1. Setup the CATransform3D structure
CATransform3D rotation;
rotation = CATransform3DMakeRotation( (90.0*M_PI)/180, 0.0, 0.7, 0.4);
rotation.m34 = 1.0/ -600;
//2. Define the initial state (Before the animation)
cell.layer.shadowColor = [[UIColor blackColor]CGColor];
cell.layer.shadowOffset = CGSizeMake(10, 10);
cell.alpha = 0;
cell.layer.transform = rotation;
cell.layer.anchorPoint = CGPointMake(0, 0.5);
//3. Define the final state (After the animation) and commit the animation
[UIView beginAnimations:#"rotation" context:NULL];
[UIView setAnimationDuration:0.8];
cell.layer.transform = CATransform3DIdentity;
cell.alpha = 1;
cell.layer.shadowOffset = CGSizeMake(0, 0);
[UIView commitAnimations];
EDIT
After going to the original site's source code again, I noticed an update to the code and I applied it:
if(cell.layer.position.x != 0){
cell.layer.position = CGPointMake(0, cell.layer.position.y);
}
However, it didn't seem to fix this issue, and I think it was a fix for another positioning issue this animation had.
i am not sure just give it a try,
just by forcing the layer position to origin, see below code
//1. Setup the CATransform3D structure
CATransform3D rotation;
rotation = CATransform3DMakeRotation( (90.0*M_PI)/180, 0.0, 0.7, 0.4);
rotation.m34 = 1.0/ -600;
//2. Define the initial state (Before the animation)
cell.layer.shadowColor = [[UIColor blackColor]CGColor];
cell.layer.shadowOffset = CGSizeMake(10, 10);
cell.alpha = 0;
cell.layer.transform = rotation;
cell.layer.anchorPoint = CGPointMake(0, 0.5);
if(cell.layer.position.x != 0)
{
cell.layer.position = CGPointMake(0, cell.layer.position.y);
}
//add this and try
CGPoint point = cell.layer.position;
point.x = 0.0f; //setting the position back to original (for your case)
cell.layer.position = point;
//4. Define the final state (After the animation) and commit the animation
[UIView beginAnimations:#"rotation" context:NULL];
[UIView setAnimationDuration:0.8];
cell.layer.transform = CATransform3DIdentity;
cell.alpha = 1;
cell.layer.shadowOffset = CGSizeMake(0, 0);
[UIView commitAnimations];

Adding a new UITableViewRow pushes the existing cells down too quickly

I am trying to create UITableCellView animation like Peek Calendar. As can be seen here:
I am using UITableView and the following code for animation
//Animaiton for the table view cells to appear
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if([cell.reuseIdentifier isEqualToString:#"HolidayCell"]) {
int x = (indexPath.row-self.selectedMonth) %2;
//1. Setup the CATransform3D structure
CATransform3D rotation;
CATransform3D position;
position = CATransform3DMakeTranslation(0, -36, 0) ;
//rotation.m33 = 12;
UILabel *shadow = (UILabel*)[cell.contentView viewWithTag:2];
//2. Define the initial state (Before the animation)
cell.alpha = 1;
shadow.alpha = 0.75;
if(x==1) {
rotation = CATransform3DMakeRotation((-90.0*M_PI)/180, 1.5, 0.0, 0.0);
rotation.m34 = 0.0059;
cell.layer.anchorPoint = CGPointMake(0.5, 0.0);
}
else
{
rotation = CATransform3DMakeRotation((90.0*M_PI)/180, 1.5, 0.0, 0.0);
rotation.m34 = 0.0059;
cell.layer.anchorPoint = CGPointMake(0.5, 1.0);
}
cell.layer.transform = CATransform3DConcat(position, rotation);
//3. Define the final state (After the animation) and commit the animation
[UIView beginAnimations:#"rotation" context:NULL];
[UIView setAnimationDuration:2.3];
//[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:cell cache:YES];
cell.layer.transform = CATransform3DIdentity;
cell.alpha = 1;
shadow.alpha = 0;
//cell.layer.shadowOff
1. List item
set = CGSizeMake(0, 0);
[UIView commitAnimations];
}
}
Now I don't have any issue in particular with the animation. The cells are rotating just fine. However my issue is that when a cell i inserted even while rotated it is still taking up space as if it were fully open.
As you can see the cells are rotating within their "virtual boxes" however I want the cells to stick together as depicted in this image:
Does anyone have any idea on how to do this?
You are not transforming the frame, only the layer. The layer is only the visual representation of the cell, and does not define size or position of the cell.
I believe, in a tableView, the frame of a cell is defined first by the heightForRowAtIndexPath: method, but you should be able to change and animate it later using the "frame" property. Try setting it to zero, and animate to the final height when the cell appears.
Code, that finally gave the solution: https://www.cocoacontrols.com/controls/jtgesturebasedtableviewdemo
Here is some code, that actually works (tested it).
Put it into the
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath method, and comment out the other code for testing
CGRect cellFrame = cell.frame;
//replace with the y coordinate of the point, where the cell(s) get inserted
float insertPoint = 0;
//replace with the duration you wish
float animationDuration = 5;
[cell setFrame:CGRectMake(cellFrame.origin.x, insertPoint, cellFrame.size.width, 0)];
[UIView animateWithDuration:animationDuration animations:^{
[cell setFrame:cellFrame];
}];
That may not be exactly what you want, but it should give you an idea...

Resources