当前位置: 首页 > 知识库问答 >
问题:

反复不断地为视图设置动画

晁文斌
2023-03-14

我在模拟一些效果,比如树叶飘落,雪和雨。我的第一个调用是使用CAEmitterLayer,它工作得很好,但我需要在上下文中渲染该层以保存为图像,这似乎是不可能的,或者至少是非常复杂的。

所以我正在处理一些视图动画。我需要不断地给我的ImageView设置动画,这样它就可以从屏幕上掉下来,然后以不同的速度重新出现在屏幕上。

所以我重新定位屏幕上的每一个图像视图,动画是动画,当动画完成时,我从完成块递归调用这样做的方法,这样图像视图就可以到达屏幕的尽头。一旦图像视图到达屏幕的尽头,我就把它重新定位在顶部。

问题是,当动画结束时,我的imageView会停止一点,直到完成块递归调用该方法,我希望它能连续运行。

我的代码为每个imageView生成随机位置,我的动画持续时间非常短,因此我可以随时更新imageView的位置,以防用户点击按钮将视图保存为图像。

不管怎样,这是我的代码:

- (void)effectOnObject:(UIImageView *)object{
    NSInteger initialX;
    NSInteger initialy;
    CGFloat duration;

    //the object have reached the end of screen
    if (object.frame.origin.y >= self.frame.size.height) {
        //generate random position to relocate the object on x axis
        initialX = arc4random() % 321;

        //generate random position to relocate the object on y axis (little bit above top of screen)
        initialy = ((NSInteger)-object.frame.size.height) - arc4random() % 11;

        //duration 0 so the object can be replaced without animation
        duration = 0.0;
    }
    else{
        initialX = object.frame.origin.x;

        //this change the speed of object
        initialy = object.frame.origin.y + 10

        //setted duration to short time
        duration = 0.01;
    }

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionAllowAnimatedContent 
     animations:^{
        [object setFrame:CGRectMake(initialX, initialy, object.frame.size.width, object.frame.size.height)];
     }
     completion:^(BOOL completed){
         //recursively call
         [self effectOnObject:object];                   
      }];
}

- (void)startEffect{

    //initiate effect on each imageView
    for (UIImageView *object in self.subviews) {
        [self effectOnObject:object];   
    }    
}

当从完成块递归调用该方法并重新启动动画时,我如何反复、连续地制作该动画,而没有间隙?

共有2个答案

陈弘厚
2023-03-14

从我简要阅读的内容中,您应该查看CAReplicatorLayer。这是完美的重复的东西!我能想到的唯一问题是,转换和值必须是增量的。。。

司空福
2023-03-14

当对象到达屏幕末端时,不需要以0持续时间制作动画。只需在完成块中进行测试,并在递归调用之前重新定位视图。此外,0.01的持续时间似乎有点极端(每秒100帧)。也许更合理的值(如0.1)会有所帮助。

比如:

- (void)effectOnObject:(UIImageView *)object{

    //setted duration to short time
    CGFloat duration = 0.1;

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionAllowAnimatedContent
                     animations:^{

                         NSInteger initialX = object.frame.origin.x;

                         //this change the speed of object
                         NSInteger initialy = object.frame.origin.y + 10;

                         [object setFrame:CGRectMake(initialX, initialy, object.frame.size.width, object.frame.size.height)];
                     }
                     completion:^(BOOL completed){

                         NSInteger initialX = arc4random() % 321;

                         //generate random position to relocate the object on y axis (little bit above top of screen)
                         NSInteger initialy = ((NSInteger)-object.frame.size.height) - arc4random() % 11;

                         [object setFrame:CGRectMake(initialX, initialy, object.frame.size.width, object.frame.size.height)];

                         //recursively call
                         [self effectOnObject:object];
                     }];
}
 类似资料:
  • 我有一个UIView,其中有一个UILabel作为子视图。 现在我用动画改变UIView的宽度(改变约束的常量属性)并在UIView动画中调用layoutIfNeed...( 视图正在正常调整大小,但UILabel(子视图)将字体大小更改为“结束”大小,但没有像uiview那样正确设置动画。 根据WWDC 2012会话,如果仅更改superview的常量,则子视图应设置动画。 UILabel的最小

  • 我有两个两个文本字段displayNameTF和emailTF。 我想设置一个文本字段的动画,使其超过另一个文本字段的顶部。 我已经将emailTF的中心存储在emailTFOrigin中,我正在将displayNameTF的中心设置为它,并设置所需的布局动画。 我得到的动画是,默认情况下,文本字段彼此相距约5点,displaynameTF直接跳到emailTF的顶部,并将动画恢复到其原始位置。

  • 7.3.1 视图配置 可配置当前视图的名称,填写备注,及设定要排除的网址查询参数。 关于排除网址查询参数 对于每个视图,在受访页面中,系统将合并此处配置的排除网址查询参数,而不体现在受访页面的后缀参数中。 其中,系统默认排除的网址参数包括 秒针规范,谷歌规范,及系统默认的自定义广告参数规范。具体字段为: mz_ca,mz_sp,mz_sb,mz_kw, utm_content,utm_term,u

  • 我有一个嵌入了谷歌地图视图的html文件,我正在使用JavaScript将一个单独的kml文件的数据加载到谷歌地图中。在KML文件中,我有汽车路线的纬度/经度坐标,我使用LineString函数将坐标连接到一条直线上。我想知道现在如何在由给定坐标绘制的线串上设置一个placemark的动画。 我已经看了这个例子,这是我试图做的,但是这个例子没有使用KML文件。此示例将通过纬度和经度坐标设置路线动画

  • SuperMap iClient for OpenLayers 通过设置 map 中 view 属性的 projection 参数来支持多投影。例如: var map = new ol.Map({ view: new ol.View({ projection: 'EPSG:4326' }); }); projection 参数除了支持 EPSG code 字符串之

  • 我正在当前视图底部的UIViewController中添加一个视图作为子视图。我可以使用alpha制作淡入淡出动画,但我想将其显示为类似键盘弹出窗口的幻灯片。 如何设置动画?