如何在Xcode中为UIView的宽度和高度设置动画?

时间:2012-10-12 04:36:12

标签: ios xcode animation uiview uiviewanimation

我有这个子视图我想添加到我的主视图中,但是要从原点扩展它。我阅读了一些Apple文档,但我不明白我在哪里弄错了。我可以设置框架原点的动画,即让它从任何地方滑入,但宽度/高度似乎没有动画。代码如下:

[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];

我还试过在动画中只放置setFrame部分,如下所示:

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];

但它仍然无效!

编辑:

根据建议,我已将其移至基于块的动画解决方案,这是确切的代码:

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) {

                 }];

由于某种原因仍然不起作用。我看到的可能问题是:

  1. 我正在从nib加载此自定义视图,具体为310 x 150,这可能会导致问题。
  2. 我没有导入正确的框架,但由于我可以为此视图的frame.origin部分设置动画,我不确定是这种情况......我有QuartzCoreCore Graphics所有进口和东西。
  3. 在日志中的每个点上,它给出正确的东西:例如,在目标帧之前,大小为0,150,并且在我将帧设置为310,150之后。但动画不起作用!< / p>

7 个答案:

答案 0 :(得分:50)

要使视图“成长”到位,请不要为框架设置动画。动画变换。

从笔尖加载子视图。将其变换设置为0:

view.transform = CGAffineTransformMakeScale(0,0);

然后将其添加到您的超级视图中。

在动画块内,将变换设置为identity:

view.transform = CGAffineTransformIdentity;

视图将增长到正常大小。您可能需要摆弄锚点,使其从正确的点开始生长。

您也可以更改块内的帧,但仅移动视图我更喜欢更改中心属性,如果您还有变换,则不应尝试设置帧。

对于奖励积分,您还可以将动画设置为略大于1.0的比例,然后在完成块的链式动画中动画回到身份转换。这使得视图像弹出视图一样从屏幕中“弹出”。

答案 1 :(得分:8)

尝试使用一个块会更清楚。

 // 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!" ); 
}];

答案 2 :(得分:3)

试试这个:

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; 
 }];

或者如果您想使用beginAnimation方法而不是阻止Methos,请使用此:

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 :(得分:1)

这是一种动画视图的有趣方式。在我的例子中,我有一个触摸动作,它将执行块动画和BOOL,以确保将视图重置回原始状态。

首先在UIViewController上放置2个UIViews(您可以为不同的颜色着色以获得对比度)。将它们连接到您创建的“MainViewController.h”文件以控制大视图。 .h文件应如下所示:

#import <UIKit/UIKit.h>

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

@end

并且您的.m文件应如下所示:

#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;
                         }];
    }

}

因此,请确保topView具有一些小尺寸,如x:0,y:0宽度:320高度:43和bottomView,如x:0 y:40宽度:320高度:528。记得给不同颜色的背景上色。然后运行该程序,你应该看到动画。

对我来说,我认为代码中更重要的一行是 setFrame:,对我来说,这使得框架能够自动重新显示矩形而无需使用DrawRect方法。设置属性会相应地更改center属性指定的点和bounds矩形中的大小。

当然还有其他有趣的方法可以做到这一点,但我希望这可以帮助有人让iOS看起来像它应该是神奇的!快乐的旅程!

答案 4 :(得分:0)

重点

1)在动画之前将视图添加到parentView,并带有起始帧。

2)然后在动画块中给出目标框架

您不再需要这个,因为您要从笔尖添加视图..

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

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

只需在视图中提供动画代码。确保你的视图不是零(在我看来就是这种情况..)

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

                 }];

答案 5 :(得分:0)

如果你的viewcontrollers viewWillLayoutSubviews(或类似)设置了你的View的“初始”框架,那么这显然会在动画周期中被调用,因此会重置动画设置的框架。

答案 6 :(得分:0)

快捷键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
    }