Hier ist eine C# Version des verknüpften schneller Controller. Einige Dinge, die ich nicht von Swift übersetzen konnte. Wäre toll, wenn jemand die Zahlenkonvertierungen überprüfen/durchdenken kann.
using CoreAnimation;
using CoreGraphics;
using UIKit;
namespace hackettyHack
{
public enum RotationDirection //int
{
// case Right = 0, Left
Right,
Left
}
public enum RotationType //int
{
// case Push = 0, Pop }
Push,
Pop
}
class FCBlackBackgroundView : UIView
{
}
class FCRotateLayer : CALayer
{
}
public class RotatingController : UINavigationController
{
public void PushViewController(UIViewController controller, RotationDirection rotateDirection)
{
Perform3DRotate(RotationType.Push, rotateDirection, controller);
}
public void PopViewController(UIViewController controller, RotationDirection rotateDirection)
{
Perform3DRotate(RotationType.Pop, rotateDirection, controller);
}
void Perform3DRotate(RotationType rotationType, RotationDirection rotateDirection, UIViewController v)
{
var layer = RotationLayer();
var cube = CubeTransform(rotateDirection, layer);
switch (rotationType)
{
case RotationType.Pop:
this.PopViewController(animated: false);
break;
case RotationType.Push:
this.PushViewController(this, animated: false); //todo: make sure the SWIFT line below for controller! means THIS
// self.pushViewController(controller!, animated: false)
break;
default:
break;
}
layer.AddSublayer(LayerFromView(this.View, cube));
this.View.AddSubview(BackgroundView(UIColor.White));
this.View.Layer.AddSublayer(layer);
layer.AddAnimation(RotationAnimation(rotateDirection), forkey: "rotate");//FIXME parameter
}
CATransform3D CubeTransform(RotationDirection rotateDirection, CALayer layer)
{
var cube = CATransform3D.MakeTranslation(0, 0, 0);//FIXME and all below
layer.AddSublayer(LayerFromView(this.View, transform: cube);
cube = CATransform3D.Rotate(cube, CGFloat(radians(90)), 0, 1, 0);
cube = CATransform3D.Translate(cube,CubeSize(), 0, 0);
if (rotateDirection == RotationDirection.Left)
{
cube = CATransform3D.Rotate(cube, CGFloat(radians(90)), 0, 1, 0);
cube = CATransform3D.Translate(cube, CubeSize(), 0, 0);
cube = CATransform3D.Rotate(cube, CGFloat(radians(90)), 0, 1, 0);
cube = CATransform3D.Translate(cube, CubeSize(), 0, 0);
}
return cube;
}
FCRotateLayer RotationLayer()
{
var layer = new FCRotateLayer();
layer.Frame = this.View.Frame;
layer.AnchorPoint = new CoreGraphics.CGPoint(x: 0.5, y: 0.5);
CATransform3D transform = CATransform3D.Identity;
transform.m34 = 1/-750;
layer.SublayerTransform = transform;
return layer;
}
CAAnimation RotationAnimation(RotationDirection direction)
{
CATransaction.Flush();
var animationGroup = new CAAnimationGroup();
animationGroup.Duration = 0.4;
var rotation = new CABasicAnimation();
var translationX = new CABasicAnimation();
if (direction == RotationDirection.Right)
{
rotation = new CABasicAnimation() { KeyPath = "sublayerTransform.rotation.y" };
//rotation.To = NSNumber(float: radians(-90))//FIXME
translationX = new CABasicAnimation() { KeyPath = "sublayerTransform.rotation.x" };
translationX.To = NSNumber(float: Float(TranslationForAnimation()));//FIXME
}
else if (direction == RotationDirection.Left)
{
rotation = new CABasicAnimation() { KeyPath = "sublayerTransform.rotation.y" };
//rotation.To = NSNumber(float: radians(90))//FIXME
translationX = new CABasicAnimation() { KeyPath = "sublayerTransform.rotation.x" };
translationX.To = NSNumber(float: Float(TranslationForAnimation()));//FIXME
}
var translationZ = new CABasicAnimation() { KeyPath = "sublayerTransform.translation.z" };
translationZ.To = NSNumber(float: Float(TranslationForAnimation()));//FIXME
animationGroup.Animations = new CAAnimation[3] { rotation, translationX, translationZ };
animationGroup.FillMode = kCAFillModeForwards; /// //FIXME TBD what is the constant? where is it?
animationGroup.RemovedOnCompletion = false;
animationGroup.Delegate = this; // or should this be = to aiimationGroup?
animationGroup.TimingFunction = CAMediaTimingFunction.FromName("kCAMediaTimingFunctionEaseInEaseOut");
return animationGroup;
}
CALayer LayerFromView(UIView view)
{
var rect = new CGRect(0, 0, this.View.Bounds.Size.Width, this.View.Bounds.Size.Height);
var imageLayer = new CALayer();
imageLayer.AnchorPoint = new CGPoint(1, 1);
imageLayer.Frame = rect;
UIGraphics.BeginImageContextWithOptions(view.Frame.Size, false, UIScreen.MainScreen.Scale);
// No idea how to convert "if..let..??" from swift.
//
//if let context = UIGraphicsGetCurrentContext() {//FIXME
//view.layer.renderInContext(context)
//}
UIImage image = new UIImage(= UIGraphics.GetImageFromCurrentImageContext();//FIXME
UIGraphics.EndImageContext();
imageLayer.Contents = image.CGImage;
return imageLayer;
}
CALayer LayerFromView(UIView view, CATransform3D transform)
{
var layer = LayerFromView(view);
layer.Transform = transform;
return layer;
}
System.nfloat Radians(System.nfloat degrees)
{
return degrees * float(M_PI)/180; //FIXME
}
System.nfloat TranslationForAnimation()
{
return CubeSize()/2;
}
System.nfloat CubeSize()
{
return UIScreen.MainScreen.Bounds.Width;
}
FCBlackBackgroundView BackgroundView(UIColor color)
{
var view = new FCBlackBackgroundView() { Frame = this.View.Frame };
view.BackgroundColor = color;
return view;
}
}
}
/*
public override func animationDidStop(anim: CAAnimation, finished flag: Bool)//FIXME no suitable overrride found
{
if let layers = self.view.layer.sublayers {
for layer in layers {
if layer.isKindOfClass(FCRotateLayer.classForCoder()) {
layer.removeFromSuperlayer()
}
}
}
for view in self.view.subviews {
if view.isKindOfClass(FCBlackBackgroundView.classForCoder()) {
view.removeFromSuperview()
}
}
}
*
*/
Ich habe meine Antwort mit der übersetzten Version aktualisiert. By the way, 'animationDidStop' ist eigentlich ein Ereignis in Xamarin (siehe [diese Dokumentation] (https://developer.xamarin.com/api/member/MonoTouch.CoreAnimation.CAAnimationDelegate.AnimationStopped/p/MonoTouch.CoreAnimation.CAAnimation/ System.Boolean /)). –