2011-11-27 14 views
2

J'ai un problème étrange avec CATransform3DMakeRotation. Lorsque la vue est tournée dans le centre du superview, il ressemble à ceci:Bizarre Perspective Avec CATransform3DMakeRotation

Valid XHTML http://i1183.photobucket.com/albums/x467/Laurin_Koppenwallner/Bildschirmfoto2011-11-27um181544.png

Voici comment il est censé regarder. Cependant, quand il est quelque part ailleurs dans le superview, par exemple, dans le coin inférieur gauche, il ressemble à ceci:

Valid XHTML http://i1183.photobucket.com/albums/x467/Laurin_Koppenwallner/Bildschirmfoto2011-11-27um181627.png

Notez qu'il est incliné vers la droite. La même chose se produit quand il est dans le coin inférieur droit, seulement qu'il s'incline vers la gauche. Y at-il un moyen de l'incliner comme il le devrait tout le temps et dans toutes les positions? Le code pour réaliser cette transformation est la suivante:

CALayer *layer = view.layer; 

    CATransform3D aTransform = CATransform3DIdentity; 
    float zDistance = 1000; 
    aTransform.m34 = 1.0/-zDistance; 

    self.view.layer.sublayerTransform = aTransform; 


    CABasicAnimation *rotateAnim = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    rotateAnim.fromValue= [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0, 0, 0, 0)]; 
    rotateAnim.duration=0.12; 
    rotateAnim.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeRotation(20*M_PI/180, 1, 0, 0)]; 

    rotateAnim.removedOnCompletion = NO; 
    rotateAnim.fillMode = kCAFillModeForwards; 
    [layer addAnimation:rotateAnim forKey:@"rotateAnim"]; 
+0

Vous ne construisez probablement pas correctement votre CATransform3D, probablement en oubliant que la translation et la rotation s'influencent mutuellement. Publiez le code que vous utilisez pour générer la transformation. –

+0

@RobNapier Inclus le code – kopproduction

Répondre

3

Vous avez appliqué perspective à la couche du superview, et c'est ce que vous obtenez. Si vous voulez une perspective basée sur les sous-couches individuelles (sans tenir compte de la perspective globale), vous devez appliquer la perspective individuellement. Par exemple:

CALayer *layer = view.layer; 

CATransform3D aTransform = CATransform3DIdentity; 
CGFloat zDistance = 2000.; 
aTransform.m34 = 1.0/-zDistance; 

CABasicAnimation *rotateAnim = [CABasicAnimation animationWithKeyPath:@"transform"]; 

rotateAnim.fromValue= [NSValue valueWithCATransform3D:aTransform]; 
aTransform = CATransform3DRotate(aTransform, 20*M_PI/180, 1, 0, 0);; 
rotateAnim.duration=0.12; 
rotateAnim.toValue=[NSValue valueWithCATransform3D:aTransform]; 
layer.transform = aTransform; 

[layer addAnimation:rotateAnim forKey:@"rotateAnim"]; 

Dans cet exemple, je demande perspective (m34) dans les deux fromValue et la toValue de la couche. Cela vous donne alors une perspective par rapport à un observateur se tenant devant la couche elle-même. Votre code original avait un observateur debout devant le centre de la vue, et donc vous obtenez une perspective biaisée.

J'ai fait quelques autres petits changements ici. Je place généralement l'observateur à 2000 au lieu de 1000. Je trouve que la perspective à 1000 est souvent plus que ce qui est désiré (à moins que vous n'ayez activement une perspective forte). Selon votre problème, vous voudrez peut-être vous débarrasser complètement de la perspective. Ne l'appliquez pas simplement par habitude.

Plus important encore, j'ai changé la façon dont vous appliquiez l'animation à la fin. L'utilisation de removedOnCompletion=NO et kCAFillModeForwards rend les choses beaucoup plus compliquées que de simplement appliquer l'animation au modèle (layer.transform=aTransform) et de laisser l'animation être supprimée normalement. En particulier, l'utilisation de removedOnCompletion=NO signifie que les demandes ultérieures de layer.transform renverront toujours l'ancienne valeur et non la valeur actuelle. Cela rend également les choses compliquées si vous appliquez d'autres animations à cette couche. C'est pourquoi la valeur par défaut est de supprimer l'animation lorsque vous avez terminé.