24

我有这个子视图,我想添加到我的主视图中,但让它从原点扩展。我阅读了一些 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. 我正在从nib310 x 150 加载这个 customView,这可能会导致问题。
  2. 我没有导入正确的框架,但是因为我可以为这个视图的 frame.origin 部分设置动画,我不确定是不是这样......我已经导入QuartzCoreCore Graphics所有的东西。

在日志中的每一点,它都给出了正确的东西:例如,在目标帧之前,大小是 0、150,在我设置帧之后,它的大小是 310、150。但是动画不起作用!

4

7 回答 7

55

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

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

view.transform = CGAffineTransformMakeScale(0,0);

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

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

view.transform = CGAffineTransformIdentity;

并且视图将增长到正常大小。您可能需要摆弄锚点以使其从正确的点增长。

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

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

于 2012-10-12T06:06:39.640 回答
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!" ); 
}];
于 2012-10-12T04:48:50.853 回答
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 方法而不是 block 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];
于 2012-10-12T04:50:11.477 回答
1

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

首先,您将 2 个 UIViews 放在 UIViewController 上(您可以为它们着色不同的颜色以进行对比)。将它们连接到您创建的“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 width:320 height:43 和 bottomView,比如 x:0 y:40 width:320 height:528。记得给背景涂上不同的颜色。然后只需运行程序,您应该会看到动画。

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

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

于 2014-02-18T19:52:55.800 回答
1

斯威夫特 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
    }
于 2018-08-06T05:42:50.227 回答
0

要点

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

2)然后只在动画块内给出目标帧

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

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

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

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

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

                 }];
于 2012-10-12T04:48:39.340 回答
0

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

于 2014-01-21T14:20:40.403 回答