Skip to content

Instantly share code, notes, and snippets.

@Krumelur
Created August 30, 2012 18:54
Show Gist options
  • Save Krumelur/3537539 to your computer and use it in GitHub Desktop.
Save Krumelur/3537539 to your computer and use it in GitHub Desktop.
CATransform3D
/// <summary>
/// Sets the anchor point and translates the view so that it stays in its current position.
/// Normally, changing the anchor point also adjusts the view's position.
/// </summary>
/// <param name='oView'>the view whose anchor point has to be modified</param>
/// <param name='oNewAnchorPoint'>the new anchor point</param>
public void SetAnchorPointAndTranslate(PointF oNewAnchorPoint )
{
UIView oView = this;
PointF oNewPoint = new PointF(oView.Bounds.Width * oNewAnchorPoint.X, oView.Bounds.Height * oNewAnchorPoint.Y);
PointF oOldPoint = new PointF(oView.Bounds.Width * oView.Layer.AnchorPoint.X, oView.Bounds.Height * oView.Layer.AnchorPoint.Y);
oNewPoint = oView.Transform.TransformPoint(oNewPoint);
oOldPoint = oView.Transform.TransformPoint(oOldPoint);
PointF oPosition = new PointF(oView.Layer.Position.X - oOldPoint.X + oNewPoint.X, oView.Layer.Position.Y - oOldPoint.Y + oNewPoint.Y);
oView.Layer.Position = oPosition;
oView.Layer.AnchorPoint = oNewAnchorPoint;
}
/// <summary>
/// Moves a tile view from left to right or right to left.
/// </summary>
/// <param name='iIndex'>zero based index of the tile to move</param>
/// <param name='eDir'>move left or right?</param>
/// <param name='bAnimate'>TRUE to animate the movement</param>
private void MoveTileView(int iIndex, UISwipeGestureRecognizerDirection eDir, bool bAnimate)
{
TileViewBase oView = this.VisibleTileViews[iIndex];
// Anchor point of the animated layer will be adjusted to rotate along the edges of the view and not the center.
// Changing the anchor point however affects the view's position. This means the changed anchor point has
// to be compensated.
if(eDir == UISwipeGestureRecognizerDirection.Left
&& oView.ViewPosition == TileViewBase.VIEW_POSITION.Center)
{
// If swiping left and the view is currently in center, the anchor point goes to the left edge.
oView.SetAnchorPointAndTranslate(new PointF(0, 0.5f));
}
if(eDir == UISwipeGestureRecognizerDirection.Right
&& oView.ViewPosition == TileViewBase.VIEW_POSITION.Center)
{
// If swiping right and the view is currently in center, the anchor point goes to the right edge.
oView.SetAnchorPointAndTranslate(new PointF(1, 0.5f));
}
// If the views are pushed aside, apply a small X offset to prevent them from sticking on top of each other.
float fOffsetX;
if(eDir == UISwipeGestureRecognizerDirection.Left)
{
fOffsetX = iIndex * TILE_DISTANCE;
}
else
{
fOffsetX = (iIndex - (this.VisibleTileViews.Length - 1)) * TILE_DISTANCE;
}
// Prepare transformation to rotate view around Y axis and translate to the left or right border of the screen.
float fAnimDir = eDir == UISwipeGestureRecognizerDirection.Left ? -1 : 1;
// TODO: Uncomment if CATransform3D no longer crashes as it does in MT 5.2.10
CATransform3D oTransform3D = CATransform3D.Identity;
oTransform3D.m34 = 1.0f / -400;
oTransform3D = oTransform3D.Translate(fAnimDir * TILE_TRANSLATION_X + fOffsetX, 0, 0);
oTransform3D = oTransform3D.Rotate(fAnimDir * (-70f) * (float)Math.PI / 180f, 0, 1, 0);
// Animate the transformation of the current view.
UIView.Animate(
bAnimate ? ANIM_CHANGE_VIEW_SECS : 0,
0f,
UIViewAnimationOptions.CurveEaseOut,
delegate
{
// Check in what direction the swipe was going (left or right).
switch(eDir)
{
case UISwipeGestureRecognizerDirection.Left:
// Swipe left. If view is centered, move to left.
// If view is right, move to center.
if(oView.ViewPosition == TileViewBase.VIEW_POSITION.Center)
{
oView.Layer.Transform = oTransform3D;
oView.ViewPosition = TileViewBase.VIEW_POSITION.Left;
}
else if(oView.ViewPosition == TileViewBase.VIEW_POSITION.Right)
{
CATransform3D oTransformCenter = CATransform3D.Identity;
oView.Layer.Transform = oTransformCenter;
oView.ViewPosition = TileViewBase.VIEW_POSITION.Center;
}
break;
case UISwipeGestureRecognizerDirection.Right:
// Swipe right. If view is centered, move to right.
// If view is left, move to center.
if(oView.ViewPosition == TileViewBase.VIEW_POSITION.Center)
{
oView.Layer.Transform = oTransform3D;
oView.ViewPosition = TileViewBase.VIEW_POSITION.Right;
}
else if(oView.ViewPosition== TileViewBase.VIEW_POSITION.Left)
{
CATransform3D oTransformCenter = CATransform3D.Identity;
oView.Layer.Transform = oTransformCenter;
oView.ViewPosition = TileViewBase.VIEW_POSITION.Center;
}
break;
}
if(oView.ViewPosition == TileViewBase.VIEW_POSITION.Center)
{
oView.Alpha = 1f;
oView.UserInteractionEnabled = true;
oView.EnableShadow(true);
}
else
{
oView.Alpha = 0.7f;
oView.UserInteractionEnabled = false;
oView.EnableShadow(false);
}
},
delegate
{
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment