2009-10-26 13 views
9

Je cherche un moyen de faire une transition UIViewAnimationTransitionCurlUp ou UIViewAnimationTransitionCurlDown sur l'iPhone mais au lieu de haut en bas, faites-le de gauche à droite (ou haut/bas en mode paysage). J'ai vu cela demandé à internet quelques fois mais aucuns pour obtenir une réponse. Cependant, je pense que c'est faisable.iPhone Curl Left et Curl Right transitions

J'ai essayé de changer la transformation de View et la transformation de view.layer mais cela n'a pas affecté la transition. Étant donné que la transition change lorsque l'appareil change d'orientation, je présume qu'il existe un moyen de tromper l'appareil pour utiliser la transition paysage en mode portrait et vice versa?

Répondre

4

J'ai réussi à obtenir cet effet en changeant l'orientation de mon UIViewController. Ce qui est étrange, c'est que mon contrôleur se nichait dans un autre quand il ne fonctionnait pas, mais quand je l'ai défini comme contrôleur de vue immédiat, cela a fonctionné.

Code qui le fait:

Dans un UIViewController qui est le contrôleur principal de la vue dans mon délégué application et ne permet que l'orientation paysage (comme vous le voyez dans la 2ème méthode ci-dessous), je donne les résultats suivants:

-(void)goToPage:(int)page flipUp:(BOOL)flipUp { 

    //do stuff... 

    // start the animated transition 
    [UIView beginAnimations:@"page transition" context:nil]; 
    [UIView setAnimationDuration:1.0]; 
    [UIView setAnimationTransition:flipUp ? UIViewAnimationTransitionCurlUp : UIViewAnimationTransitionCurlDown forView:self.view cache:YES]; 

    //insert your new subview 
    //[self.view insertSubview:currentPage.view atIndex:self.view.subviews.count]; 

     // commit the transition animation 
     [UIView commitAnimations]; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); 
} 
+0

Qu'en est-il de la barre d'état? - barre d'état va regarder sur le côté droit - lors de l'utilisation de l'application? –

+3

Cela ne semble pas fonctionner. – adib

+0

Assurez-vous que votre View Controller n'est pas imbriqué, ou s'il s'assure que ses parents implémentent la bonne orientation ... – Dimitris

0

Je ne pense pas qu'il y ait moyen d'écrire une animation personnalisée.

Plus important encore, vous ne devriez probablement pas essayer. L'enroulement et l'enroulement font partie de la grammaire de l'interface utilisateur qui indique à l'utilisateur qu'une vue est levée ou déposée sur la vue existante. C'est censé être comme une note collante posée puis retirée. Un virage à gauche sera probablement interprété comme quelque chose comme déchirer une page d'un livre. Il va confondre les utilisateurs. Chaque fois que vous essayez de faire quelque chose dans l'interface que l'API standard ne fait pas facilement, vous devez vous demander si une méthode aussi nouvelle communiquera quelque chose d'important à l'utilisateur et si elle est similaire à la grammaire de l'interface existante . Si non, alors vous ne devriez pas déranger.

Les interfaces inhabituelles ont un facteur de wow initial, mais elles conduisent à des frustrations et des erreurs dans l'utilisation au jour le jour. Ils peuvent également amener Apple à refuser votre application.

+0

Ce n'est pas inhabituel. C'est exactement pareil. En fait, Apple le fait, juste dans l'orientation opposée. Je suis en train de créer un livre de paysages interactif, donc je suis certain que cette animation communiquera le sentiment du livre à l'utilisateur. L'effet haut-bas fonctionne pour les ordinateurs portables (comme l'application de notes). Mais pour un bon livre, j'ai besoin d'un sentiment différent. – Dimitris

+0

Si vous regardez la transition curl, vous verrez qu'elle détache trois coins de la vue. Une page tournée n'en détache que deux. La boucle déplace la vue en diagonale tandis qu'un tour de page se déplace uniquement de gauche à droite. La différence est subtile mais importante pour les attentes des utilisateurs. – TechZen

+2

Je ne pense pas que vous pouvez obtenir la transition que vous voulez par une transformation simple parce que le mouvement principal dans la transition de boucle est le mouvement diagonal du coin inférieur droit. Peu importe comment vous tournez ou transformez la vue, ce mouvement diagonal restera ce qui détruira l'illusion d'une simple boucle de gauche à droite. – TechZen

9

Il est possible de faire des boucles dans l'une des quatre directions en utilisant une vue de conteneur. Définissez la vue de la transformation de conteneurs à l'angle que vous voulez et ensuite faire la boucle en ajoutant votre point de vue à la vue du récipient, pas vue principale de votre application qui ne dispose pas d'un cadre transformé:

NSView* parent = viewController.view; // the main view 
NSView* containerView = [[[UIView alloc] initWithFrame:parent.bounds] autorelease]; 
containerView.transform = CGAffineTransformMakeRotation(<your angle here, should probably be M_PI_2 * some integer>); 
[parent addSubview:containerView]; 

[UIView beginAnimations:nil context:nil]; 
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:containerView cache:YES]; 
[containerView addSubview:view]; 
[UIView commitAnimations]; 
+0

Quelle est la vue que vous ajoutez à [email protected] –

2

J'ai aussi eu du mal avec cela. Pour obtenir la boucle à droite ou à gauche, vous pouvez créer une vue intermédiaire et la transformer.Alors, disons que la vue que vous êtes la transition (myView) est un enfant de la fenêtre principale (parentView):

-parentView 
-->myView 

Vous insérez une vue intermédiaire entre (facilement fait dans Interface Builder):

-parentView 
-->containerView 
--->myView 

Ensuite, utilisez le code suivant pour retourner le conteneur 90 degrés à gauche et la vue 90 degrés à droite transition:

containerView.transform = CGAffineTransformMakeRotation(-M_PI_2); 
myView.transform = CGAffineTransformMakeRotation(M_PI_2); 

myView apparaît encore debout à l'utilisateur, mais la transition pense qu'il est appliqué à 90 degrés de la gauche.

Notez que selon la façon dont l'auto-mise à l'échelle sont vos points de vue, vous pourriez avoir à fixer les tailles de châssis après avoir appliqué la transformation, par exemple

containerView.frame = CGRectMake(0.0, 0.0, 768.0, 1024.0); 
    myWebView.frame = CGRectMake(0.0, 0.0, 768.0, 1024.0); 

Hope this helps. C'est le plus proche, vous pouvez obtenir à UIViewAnimationTransitionCurlLeft et UIViewAnimationTransitionCurlRight.

+0

Excellente réponse! Votre recette fonctionne comme un charme. – Bram

2

J'ai essayé la solution de fluXa sur iOS5 (donc j'ai dû utiliser [UIView trans ......]) mais cela n'a pas fonctionné: la boucle était toujours montée ou descendue. Apparemment, la transition ne tient pas compte de la transformation de la vue. Donc, dans le cas où quelqu'un d'autre veut faire le même tour sur iOS5, la solution est d'ajouter un autre conteneur entre les deux et d'animer la transition à partir de là.

Voici mon code, qui est un peu spécifique puisque je veux boucler 'vers le haut' vers la gauche, mais avec le coin inférieur curling. Comme si je déchirais une page d'un carnet de notes.

UIView* parent = self.view; // the main view 
CGRect r = flipRectSize(parent.bounds); 
UIView* containerView = [[UIView alloc] initWithFrame:r]; 
CGAffineTransform t = CGAffineTransformMakeRotation(-M_PI_2); 
t = CGAffineTransformTranslate(t, -80, -80); 
containerView.transform = CGAffineTransformScale(t, -1, 1); 
[parent addSubview:containerView]; 

UIView* container2 = [[UIView alloc] initWithFrame:r]; 
[containerView addSubview:container2]; 

UIImageView* v = [[UIImageView alloc] initWithFrame:r]; 
v.image = [UIImage imageWithCGImage:contents.CGImage scale:contents.scale orientation:UIImageOrientationLeftMirrored]; 
[container2 addSubview:v]; 

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.001 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 
    [UIView transitionWithView:container2 
         duration:DURATION_CURL_ANIMATION 
         options:UIViewAnimationOptionTransitionCurlUp 
        animations:^{ 
         [v removeFromSuperview]; 
        } completion:^(BOOL finished) { 
         if (completion) { 
          completion(finished); 
         } 
         [containerView removeFromSuperview];}];}); 

Notes:

  1. Je dois admettre que affines transform traduire (80,80) n'a pas de sens dans mon esprit, mais il est nécessaire pour l'iphone, ne fonctionnera probablement pas sur iPad. FlipSizeRect retourne la largeur et la hauteur d'un rectangle (vous l'avez déjà obtenu, n'est-ce pas?)
  2. le dispatch_after est nécessaire car j'ai ajouté le conteneur, puis je souhaite supprimer une vue de la hiérarchie. Si je laisse tomber la dépêche, rien ne l'anime. Ma meilleure supposition est que nous devons d'abord laisser le système faire un passage de disposition avant que nous puissions animer une suppression.