2012-01-04 8 views
3

J'apprécierais vraiment toute aide sur celui-ci. J'ai appliqué une transformation 3D sur une vue et j'ai besoin d'identifier les coordonnées de bord de la vue rendue afin de pouvoir présenter une autre vue adjacente à celle-ci (sans aucun espace entre les pixels). Plus précisément, je veux qu'une série de vues («pages») se replie comme un dépliant, en animant l'angle.iOS CATransform3D Coordonnées

int dir = (isOddNumberedPage ? 1 : -1); 
    float angle = 10.0; 

    theView.frame = CGRectMake(pageNumber * 320, 0, 320, 460);   
    CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity; 
    rotationAndPerspectiveTransform.m34 = -1.0/2000; // Perspective 
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 
      dir * angle/(180.0/M_PI), 0.0f, 1.0f, 0.0f); 
    theView.layer.transform = rotationAndPerspectiveTransform; 

    // Now need to get the top, left, width, height of the transformed view to correct the view's left offset 

J'ai essayé plusieurs façons de le faire en inspectant le CALayer, une tentative ratée à l'aide de quelques extraits de code mathématique de la matrice que j'ai trouvé, mais n'ont pas été en mesure de se fissurer ou même se rapprocher (selon angle, un bon 20 pixels). Y at-il un moyen de le faire sans passer 2 semaines à lire un manuel de mathématiques matricielles?

Répondre

5

Le cadre d'une vue est un rectangle aligné sur l'axe dans le système de coordonnées de la vue d'ensemble. Le cadre entoure complètement les limites de la vue. Si la vue est transformée, le cadre s'ajuste étroitement aux nouvelles limites de la vue. Lorsque vous appliquez une rotation d'axe Y et une perspective à une vue, les bords gauche et droit de la vue se déplacent vers son point d'ancrage (qui est normalement le centre de la vue). Le bord gauche croît aussi plus haut ou plus court, et le bord droit fait le contraire. Ainsi, le cadre de la vue (après application de la transformation) vous donnera la coordonnée du bord gauche et la largeur de la vue transformée, ainsi que le sommet et la hauteur du bord supérieur (qui peut être le bord gauche ou droit).). Voici mon code de test:

NSLog(@"frame before tilting = %@", NSStringFromCGRect(self.tiltView.frame)); 
float angle = 30.0; 
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity; 
rotationAndPerspectiveTransform.m34 = -1.0/2000; // Perspective 
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 
     1 * angle/(180.0/M_PI), 0.0f, 1.0f, 0.0f); 
self.tiltView.layer.transform = rotationAndPerspectiveTransform; 
NSLog(@"frame after tilting = %@", NSStringFromCGRect(self.tiltView.frame)); 

est ici la sortie:

2012-01-04 12:44:08.405 layer[72495:f803] frame before tilting = {{50, 50}, {220, 360}} 
2012-01-04 12:44:08.406 layer[72495:f803] frame after tilting = {{62.0434, 44.91}, {190.67, 370.18}} 

Vous pouvez également obtenir les coordonnées des coins de la vue, dans l'espace de coordonnées du superview en utilisant convertPoint:fromView: ou convertPoint:toView:. Code d'essai:

CGRect bounds = self.tiltView.bounds; 
    CGPoint upperLeft = bounds.origin; 
    CGPoint upperRight = CGPointMake(CGRectGetMaxX(bounds), bounds.origin.y); 
    CGPoint lowerLeft = CGPointMake(bounds.origin.x, CGRectGetMaxY(bounds)); 
    CGPoint lowerRight = CGPointMake(upperRight.x, lowerLeft.y); 
#define LogPoint(P) NSLog(@"%s = %@ -> %@", #P, \ 
    NSStringFromCGPoint(P), \ 
    NSStringFromCGPoint([self.tiltView.superview convertPoint:P fromView:self.tiltView])) 
    LogPoint(upperLeft); 
    LogPoint(upperRight); 
    LogPoint(lowerLeft); 
    LogPoint(lowerRight); 

sortie:

2012-01-04 13:03:00.663 layer[72635:f803] upperLeft = {0, 0} -> {62.0434, 44.91} 
2012-01-04 13:03:00.663 layer[72635:f803] upperRight = {220, 0} -> {252.713, 54.8175} 
2012-01-04 13:03:00.663 layer[72635:f803] lowerLeft = {0, 360} -> {62.0434, 415.09} 
2012-01-04 13:03:00.663 layer[72635:f803] lowerRight = {220, 360} -> {252.713, 405.182} 

Notez que les coordonnées Y des points supérieur gauche et upperRight sont différents dans le système de coordonnées du superview.

+0

Merci Rob - vous êtes une star absolue. J'en ai pris quelques-uns pour que ça marche dans mon scénario, mais votre explication était sur place, alors j'ai été là. – Phil

Questions connexes