Created
August 30, 2012 18:54
-
-
Save Krumelur/3537539 to your computer and use it in GitHub Desktop.
CATransform3D
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <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