web-dev-qa-db-fra.com

Comment animer la largeur et la hauteur d'un UIView dans Xcode?

J'ai cette sous-vue que je veux ajouter à ma vue principale, mais la développez à partir de l'origine. J'ai lu une partie de la documentation Apple mais je ne comprends pas où je me trompe. Je peux animer l’origine du cadre, c’est-à-dire le faire glisser de n’importe où, mais la largeur/hauteur ne semble pas animer. Code comme suit:

[UIView beginAnimations:@"animateAddContentView" context:nil];
[UIView setAnimationDuration:0.4];
customView.frame= CGRectMake(self.view.frame.Origin.x +5, self.view.frame.Origin.y +5, 0, 150);
[self.view addSubview:customView];

customView.frame= CGRectMake(self.view.frame.Origin.x +5, self.view.frame.Origin.y +5, 310, 150);
[UIView commitAnimations];

J'ai aussi essayé de ne mettre que la partie setFrame dans l'animation comme ceci: 

customView.frame= CGRectMake(self.view.frame.Origin.x +5, self.view.frame.Origin.y +5, 0, 150);
[self.view addSubview:customView];
[UIView beginAnimations:@"animateAddContentView" context:nil];
[UIView setAnimationDuration:0.4];
customView.frame= CGRectMake(self.view.frame.Origin.x +5, self.view.frame.Origin.y +5, 310, 150);
[UIView commitAnimations];

Mais ça ne marche toujours pas! 

MODIFIER: 

Selon les suggestions, je l'ai déplacé vers une solution d'animation basée sur des blocs, et voici le code exact:

NSLog(@"yourview : %@",customView);
customView.frame= CGRectMake(self.view.frame.Origin.x +5, self.view.frame.Origin.y +5, 0, 150);

NSLog(@"yourview : %@",customView);
[self.view addSubview:customView];
NSLog(@"yourview : %@",customView);

//    [customView setFrame:CGRectMake( 0.0f, 480.0f, customView.frame.size.width, customView.frame.size.height)];

[UIView animateWithDuration:0.4
                      delay:0
                    options:UIViewAnimationCurveEaseInOut
                 animations:^ {
                     NSLog(@"yourview : %@",customView);

                     customView.frame = CGRectMake(self.view.frame.Origin.x +5, self.view.frame.Origin.y +5, 310, 150);
                     NSLog(@"yourview : %@",customView);

                 }completion:^(BOOL finished) {

                 }];

Ce qui ne fonctionne toujours pas pour une raison quelconque. Les problèmes possibles que je vois sont:

  1. Je charge cette vue personnalisée à partir d'une nib qui est spécifiquement 310 par 150, peut-être que cause un problème.
  2. Je ne suis pas en train d'importer les bons frameworks, mais comme je peux animer le frame.Origin de cette vue, je ne suis pas sûr que ce soit le cas ... J'ai QuartzCore et Core Graphics tous importés et d'autres choses.

À chaque endroit dans le journal, le contenu est correct: par exemple, avant l'image cible, la taille est 0, 150, et après avoir défini l'image 310, 150. Mais l'animation ne fonctionne pas!

22
Hudson Buddy

Pour faire "grandir" une vue, n'animez pas le cadre. Animez la transformation. 

Chargez votre sous-vue depuis la plume. Définissez sa transformation sur une échelle de 0:

view.transform = CGAffineTransformMakeScale(0,0);

Puis ajoutez-le à votre superview. 

Dans le bloc d'animation, définissez la transformation sur identité:

view.transform = CGAffineTransformIdentity;

Et la vue atteindra une taille normale. Vous devrez peut-être jouer avec le point d'ancrage pour le faire grandir à partir du bon point. 

Vous pouvez également modifier le cadre dans le bloc, mais pour déplacer uniquement une vue, je préfère modifier la propriété center. Vous ne devez pas essayer de définir le cadre si vous avez également une transformation. 

Pour les points bonus, vous pouvez également animer une échelle légèrement supérieure à 1,0, puis revenir à la transformation d'identité en une animation chaînée à partir du bloc d'achèvement. Cela fait en sorte que la vue "sorte" de l'écran comme une vue d'alerte. 

50
jrturton

Essayez d'utiliser un bloc, il sera plus clair. 

 // First create the view if you haven't already 
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)]; 
// Add it as a subview. 
[myViewController.view addSubview:myView]; 


CGRect newFrameOfMyView = CGRectMake(0.0f, 0.0f, 200.0f, 200.0f); 
/*
 * Alternatively you could just set the width/height or whatever you'd like with this: 
 * CGRect newFrameOfMyView = myView.frame; 
 * newFrameOfMyView.size.height = 200.0f; 
 * newFrameOfMyView.size.width = 200.0f; 
 */
[UIView animateWithDuration:0.3f
     animations:^{
      myView.frame = newFrameOfMyView; 
     }
     completion:^(BOOL finished){ 
     NSLog( @"woo! Finished animating the frame of myView!" ); 
}];
8
Alec

Essaye ça:

customView.frame= CGRectMake(self.view.frame.Origin.x +5,self.view.frame.Origin.y+5,0, 150);
[self.view addSubview:customView];
CGRect frame = customView.frame;
frame.size.width = 310;
[UIView animateWithDuration:0.4
 animations:^{
  customView.frame= frame; 
 }];

Ou si vous souhaitez utiliser la méthode beginAnimation au lieu de bloquer Methos, utilisez ceci:

UIView *customView=[[UIView alloc]initWithFrame:CGRectMake(self.view.frame.Origin.x +5,self.view.frame.Origin.y+5,0, 150)];
[self.view addSubview:customView];
CGRect frame = customView.frame;
frame.size.width = 310;
[UIView beginAnimations:@"animateAddContentView" context:nil];
[UIView setAnimationDuration:0.4];
customView.frame= frame;
[UIView commitAnimations];
3
Ankit

Voici une manière amusante d’animer vos vues. Dans mon exemple, j'ai une action tactile qui va exécuter les animations de bloc et un BOOL pour être sûr de remettre les vues à leur état d'origine.

Tout d'abord, vous placez 2 UIViews sur un UIViewController (vous pouvez les colorer de différentes couleurs pour le contraste). Connectez-les au fichier "MainViewController.h" que vous créez pour contrôler la grande vue . Le fichier .h devrait ressembler à ceci:

#import <UIKit/UIKit.h>

@interface MainViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIView *topView;
@property (weak, nonatomic) IBOutlet UIView *bottomView;

@end

et votre fichier .m devrait ressembler à ceci:

#import "MainViewController.h"
#define kViewAnimateWithDuration 0.35f
#define kViewDelay 0.05f

@interface MainViewController ()
@property (nonatomic) BOOL setTouch;
@end

@implementation MainViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        self.setTouch = NO;
    }
    return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInView:self.view];

    float width_tp = self.topView.frame.size.width;
    float height_tp = self.topView.frame.size.height;

    float width_b = self.bottomView.frame.size.width;
    float height_b = self.bottomView.frame.size.height;

    if ((CGRectContainsPoint(self.bottomView.frame, touchLocation)) && !self.setTouch){

        [UIView animateWithDuration:kViewAnimateWithDuration
                              delay:kViewDelay
                            options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                         animations:^{
                             //Move frame or transform view
                             [self.topView setFrame:CGRectMake(self.topView.frame.Origin.x, self.topView.frame.Origin.y, width_tp, height_tp + 171)];

                             [self.bottomView setFrame:CGRectMake(self.bottomView.frame.Origin.x, self.bottomView.frame.Origin.y +171, width_b, height_b -171)];

                         } completion:^(BOOL finished) {
                             self.setTouch = YES;
                         }];



    }
    if ((CGRectContainsPoint(self.bottomView.frame, touchLocation)) && self.setTouch) {
        [UIView animateWithDuration:kViewAnimateWithDuration
                              delay:kViewDelay
                            options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                         animations:^{
                             //Move frame or transform view
                             [self.topView setFrame:CGRectMake(self.topView.frame.Origin.x, self.topView.frame.Origin.y, width_tp, height_tp - 171)];

                             [self.bottomView setFrame:CGRectMake(self.bottomView.frame.Origin.x, self.bottomView.frame.Origin.y -171, width_b, height_b +171)];

                         } completion:^(BOOL finished) {
                             self.setTouch = NO;
                         }];
    }

}

Assurez-vous simplement que topView a de petites dimensions comme x: 0, y: 0 width: 320 height: 43 et bottomView comme x: 0 y: 40 width: 320 height: 528. N'oubliez pas de colorer les arrière-plans de différentes couleurs. Ensuite, lancez simplement le programme et vous devriez voir des animations.

Pour moi, je pense que l’une des lignes les plus importantes du code est setFrame: me permet au cadre de réafficher automatiquement le rectangle sans avoir à utiliser la méthode DrawRect. La définition de la propriété modifie le point spécifié par la propriété center et la taille dans le rectangle de limites en conséquence.

Bien sûr, il existe d'autres moyens amusants de le faire, mais j'espère que cela aidera quelqu'un à donner à iOS un aspect magique comme il est censé l'être! Bonne route!

1
tony.stack

Si vos contrôleurs de vues viewWillLayoutSubviews (ou autres) définissent la trame "initiale" de yourView, celle-ci est apparemment appelée pendant le cycle d'animation et réinitialise par conséquent le cadre défini par l'animation. 

0
mtkopone

Swift 4

  UIView.animate(withDuration: 0.3, animations: {
        self.whiteBackgroundView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
        self.view.layoutIfNeeded()
    }) { (finished) in
        // end of animation
    }
0
Alfi

Les points importants

1) Ajoutez une vue à votre vue parent avant l’animation, avec la première image.

2) Ensuite, donnez simplement l'image cible à l'intérieur du bloc d'animation

Vous n'en avez plus besoin depuis que vous ajoutez une vue de nib.

//UIVIew yourView  = [[UIView alloc] initWithFrame:YOUR_STARTING_FRAME];
//[self.view addSubview:yourView];

.........
.........
.........

donnez simplement le code d'animation sur votre vue .. Assurez-vous que votre vue n'est pas nulle (il me semble que c'est le cas ..)

NSLog(@"yourview : %@",yourView);
[UIView animateWithDuration:your_duration 
                      delay:your_starting_delay 
                    options:UIViewAnimationCurveEaseInOut 
                 animations:^ {
                     yourView.frame = YOUR_TARGET_FRAME;
                 }completion:^(BOOL finished) {

                 }];
0
Krishnabhadra