Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在不同时间设置更改高度和宽度的动画_Ios_Objective C_Animation_Transform_Cgaffinetransform - Fatal编程技术网

Ios 在不同时间设置更改高度和宽度的动画

Ios 在不同时间设置更改高度和宽度的动画,ios,objective-c,animation,transform,cgaffinetransform,Ios,Objective C,Animation,Transform,Cgaffinetransform,我有一个图像,我是动画,以使它看起来好像是“呼吸” 目前,我用下面的代码使图像以一种体面的方式移动:(我正在制作一个包含几个UIImageView的UIView的动画,这些UIImageView都作为一个整体移动) 然而,我似乎不知道如何以与y不同的速率在x方向拉伸图像。这一点是要让图像看起来像是真实存在的,而不是通过清晰的重复运动来循环 我尝试将UIView的中心定位到一个特定的位置,然后通过一个1.0秒的动画为宽度添加一些数字。 然后我尝试同时调用另一个动画,该动画只对高度执行相同的动画,添

我有一个图像,我是动画,以使它看起来好像是“呼吸”

目前,我用下面的代码使图像以一种体面的方式移动:(我正在制作一个包含几个UIImageView的UIView的动画,这些UIImageView都作为一个整体移动)

然而,我似乎不知道如何以与y不同的速率在x方向拉伸图像。这一点是要让图像看起来像是真实存在的,而不是通过清晰的重复运动来循环

我尝试将
UIView
的中心定位到一个特定的位置,然后通过一个1.0秒的动画为宽度添加一些数字。 然后我尝试同时调用另一个动画,该动画只对高度执行相同的动画,添加了不同的数量,持续约1.3秒。但是我不能让这两个同时执行,因为一个会优先于另一个


如果有人能引导我在正确的方向上,以不同的速度重复拉伸宽度和高度,我将非常感激。谢谢

考虑两个在时间上重叠的变化如下所示:

        |---- change x ---|
   |---- change y ----|
如果两个间隔任意且重叠,则可以用三个动画表示:一个单独更改一个维度,一个同时更改两个维度,另一个单独更改一个维度

您可以看到有许多方法可以指定这一点,但让我们尝试一种直接的方法。为了避免复合比例的运算,让我们指定一个维度、像素变化和持续时间。例如

@[ @{@"dimension":@"width", @"delta":@10, @"duration":0.2},
   @{@"dimension":@"both", @"delta":@40, @"duration":0.8}, 
   @{@"dimension":@"width", @"delta":@10, @"duration":0.2} ]
。。。指跨越较短高度变化的较长宽度变化。您可以看到,这是一种非常完整的语言,可以实现您想要的功能

我们需要一个动画方法,将执行连续的变化。一种简单的方法是将操作数组视为待办事项列表。递归算法说:要做一系列事情,先做第一件,然后做其余的

- (void)animateView:(UIView *)view actions:(NSArray *)actions completion:(void (^)(BOOL))completion {
    if (actions.count == 0) return completion(YES);
    NSDictionary *action = actions[0];
    NSArray *remainingActions = [actions subarrayWithRange:NSMakeRange(1, actions.count-1)];
    [self animateView:view action:action completion:^(BOOL finished) {
        [self animateView:view actions:remainingActions completion:completion];
    }];
}
对于动画,您可能希望在中间动画中使用线性计时曲线,尽管我可以看到您变得更加精细,并在列表的开始和结束处更改计时曲线

- (void)animateView:(UIView *)view action:(NSDictionary *)action completion:(void (^)(BOOL))completion {
    NSString *dimension = action[@"dimension"];
    CGFloat delta = [action[@"delta"] floatValue];
    NSTimeInterval duration = [action[@"duration"] floatValue];

    CGRect frame = view.frame;

    if ([dimension isEqualToString:@"width"]) {
        frame = CGRectInset(frame, -delta, 0);
    } else if ([dimension isEqualToString:@"height"]) {
        frame = CGRectInset(frame, 0, -delta);
    } else {
        frame = CGRectInset(frame, -delta, -delta);
    }
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
        view.frame = frame;
    } completion:completion];
}

如果字典数组太笨拙而无法指定(而且相当通用),您可以在顶部添加一些方便的方法,为调用者提供一些更简单的方案,并构建更通用的表示数组。

感谢您的深入响应-我一直在处理类似的理论,但在准确执行它时遇到了一些困难。希望这最终能引导我走向正确的方向。如果是我,我会把它放在它自己的小项目中(或者至少在你当前的项目中放在它自己的视图控制器中),然后随便组合一下。一开始我会用很长的时间来观察发生了什么。
- (void)animateView:(UIView *)view action:(NSDictionary *)action completion:(void (^)(BOOL))completion {
    NSString *dimension = action[@"dimension"];
    CGFloat delta = [action[@"delta"] floatValue];
    NSTimeInterval duration = [action[@"duration"] floatValue];

    CGRect frame = view.frame;

    if ([dimension isEqualToString:@"width"]) {
        frame = CGRectInset(frame, -delta, 0);
    } else if ([dimension isEqualToString:@"height"]) {
        frame = CGRectInset(frame, 0, -delta);
    } else {
        frame = CGRectInset(frame, -delta, -delta);
    }
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
        view.frame = frame;
    } completion:completion];
}