Question

Je cherche un moyen d'effectuer 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 cette question posée à plusieurs reprises sur Internet, mais rien ne permet d'obtenir une réponse. Cependant, j'estime que c'est faisable.

J'ai essayé de modifier la transformation de la vue et celle de view.layer, mais cela n'a pas affecté la transition. Étant donné que la transition change lorsque l’appareil change d’orientation, je suppose qu’il existe un moyen de le tromper pour utiliser la transition Paysage en mode portrait et vice-versa?

Était-ce utile?

La solution 2

J'ai effectivement réussi à obtenir cet effet en modifiant l'orientation de mon UIViewController. Ce qui est étrange, c’est que j’avais mon contrôleur niché dans un autre quand il ne fonctionnait pas, mais lorsque je l’ai défini comme contrôleur de vue immédiate, cela a fonctionné.

Code qui le fait:

Dans un UIViewController qui est le contrôleur de vue principal dans mon délégué d'application et n'autorise que l'orientation paysage (comme vous le voyez dans la seconde méthode ci-dessous), j'ai les éléments 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);
}

Autres conseils

Il est possible de faire des boucles dans n’importe laquelle des quatre directions en utilisant une vue conteneur. Définissez la transformation de la vue conteneur sur l'angle souhaité, puis effectuez le curl en ajoutant votre vue à la vue conteneur, et non à la vue principale de votre application qui ne contient pas de 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];

J'ai aussi eu du mal avec ça. Pour que la boucle vienne de droite ou de gauche, vous pouvez créer une vue intermédiaire et la transformer. Supposons donc que la vue en cours de transition (myView) soit un enfant de la fenêtre principale (parentView):

-parentView
-->myView

Vous allez insérer une vue intermédiaire entre-deux (facile à réaliser dans Interface Builder):

-parentView
-->containerView
--->myView

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

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

myView apparaîtra toujours à la verticale de l'utilisateur, mais la transition pensera qu'elle est appliquée à 90 degrés de la gauche.

Notez que, selon le degré de redimensionnement automatique de vos vues, vous devrez peut-être définir la taille des images après l'application de 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);

J'espère que ça aide. Vous vous rapprochez le plus de UIViewAnimationTransitionCurlLeft et de UIViewAnimationTransitionCurlRight.

J'ai essayé la solution fluXa sur iOS5 (je devais donc utiliser [UIView trans ......]), mais cela n'a pas fonctionné: la boucle était toujours ascendante ou descendante. Apparemment, la transition maintenant ne prend pas en compte la transformation de la vue. Donc, si quelqu'un d'autre veut faire la même chose sur iOS5, la solution consiste à ajouter un autre conteneur entre les deux et d'animer la transition à partir de là.

Voici mon code, qui est un peu spécifique car je veux me rouler "vers le haut" à 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 la transformation affine (80,80) n'a pas de sens dans mon esprit, mais elle est nécessaire pour iphone et ne fonctionnera probablement pas sur iPad.
  2. flipSizeRect retourne la largeur et la hauteur d’un rectangle (vous l’avez déjà compris, non?)
  3. dispatch_after est nécessaire car j'ai ajouté le conteneur et que je souhaite ensuite supprimer une vue de la hiérarchie. Si je laisse la dépêche, rien ne s'anime. Ma meilleure hypothèse est que nous devons d'abord laisser le système effectuer une mise en page avant de pouvoir animer une suppression.

Je ne pense pas qu'il existe un moyen autre que d'écrire une animation personnalisée.

Plus important encore, vous ne devriez probablement pas essayer. Le repliement et le repliement font partie de la grammaire de l'interface utilisateur qui indique à l'utilisateur qu'une vue est en train d'être levée ou posée sur la vue existante. C'est supposé être comme un post-it qui est déposé puis enlevé. Un & Lt; - & Gt; left curl sera probablement interprété comme quelque chose comme déchirer une page d'un livre. Cela va dérouter les utilisateurs.

Chaque fois que vous essayez de faire quelque chose dans l'interface que l'API standard ne permet pas facilement, vous devez vous demander si une telle méthode nouvelle communiquera quelque chose d'important à l'utilisateur et si elle est similaire à la grammaire d'interface existante. Sinon, ne vous embêtez pas.

Les interfaces inhabituelles ont un facteur wow initial, mais elles conduisent à la frustration et à des erreurs lors de l’utilisation quotidienne. Ils peuvent également amener Apple à refuser votre application.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top