尝试同时动画两个UIView,但只有一个会移动

7
我正试图在我的iOS应用程序中创建一项动画,在新视图从左侧滑入屏幕时,主视图向右滑动以为其腾出空间。主视图是视图控制器顶部视图的子视图,而滑入的侧边视图则从单独的xib文件加载。
如果相关的话,这里是我加载侧边视图的代码,调用自我的主视图控制器的viewDidLoad方法:
sideViewController = [[SideViewController alloc] init];
[sideViewController loadView];

sideView = sideViewController.topView;
[self.view addSubview:sideView];
sideView.hidden = YES;
sideView.frame = CGRectMake(-200, 0, 200, 460);

下面是用于动画两个视图的代码:

sideView.hidden = NO;
[UIView animateWithDuration:0.25f
                 animations:^{                         
                     mainView.frame = CGRectMake(200, 0, 320, 460);
                     sideView.frame = CGRectMake(0, 0, 200, 460);
                 }];

这似乎很简单。但不知什么原因,只有sideView动画——mainView没有移动到任何地方。更令人困惑的是,如果我注释掉动画块中移动sideView的行,那么mainView的动画就开始工作了。
有人知道是什么问题吗?从我阅读的所有搜索和文档来看,我所做的应该正常工作。我认为这将是一个简单的动画,却变成了数小时的挫折。任何帮助都将不胜感激!
编辑:
根据Guo Luchuan的建议,我尝试对两个UIView的不同属性进行动画。大多数都得到了相同的结果,尽管对它们的转换属性进行动画几乎有效。在这种情况下,两个UIView都进行了动画,但mainView只是做错了事情:它的动画始于不同的位置,并以错误的位置结束。看起来它正在执行我指示它执行的平移,但从这个表达式计算的位置开始:
starting_point - 0.5 * total_translation

意思是它在此结束:

starting_point + 0.5 * total_translation

然而,sideView的动画效果是正确的。

这真是令人恼火。我没想到在iOS上执行动画会如此不稳定。我接下来要尝试的是使用CABasicAnimation,尽管我很不高兴必须为了这么简单的事情而尝试使用这样一个低级别的API。

4个回答

4
我遇到了和你一样的问题。
当我在UIView动画块中同时设置两个视图的相同属性(如frame或transform)时,它不会按照我的期望工作。
所以,我将一个视图设置为frame,另一个视图设置为transform,这样就可以正常工作了,但我不知道为什么会这样。
我认为这对你也会有效。
sideView.hidden = NO;
[UIView animateWithDuration:0.25f
                 animations:^{                         
                     mainView.frame = CGRectMake(200, 0, 320, 460);
                     sideView.transform = CGAffineTransformMakeTranslation(200,0);
                 }];

我认为你可以创建两个CABasicAnimation,然后将它们添加到CAAnimationGroup中。这也可以为您工作。


这是一个很好的建议,虽然我尝试了一下,但它没有起作用。实际上,我已经尝试了几种不同属性的组合进行动画处理,但要么得到了相同的结果,要么得到了错误的结果。我将编辑我的主贴以更详细地说明。 - Bri Bri

3

问题出在我的xib文件上启用了自动调整大小。当我关闭它后,我的原始动画代码就可以完美运行了。


我曾经遇到过同样的问题,而且也开启了autoLayout。不幸的是,关闭它并没有帮助我解决问题...虽然我可能错过了全局关闭它的地方(我正在使用代码构建我的屏幕)。我找到的一个解决方案是将两个视图嵌入到父容器视图中,然后只对其进行动画处理。 - avance

0
如果sideViewmainView子视图,请使用此动画方法:
+animateWithDuration:delay:options:animations:completion:

使用选项:

UIViewAnimationOptionAllowAnimatedContent

sideView 和 mainView 是我的视图控制器顶部视图下的兄弟视图,所以这不适用。然而奇怪的是,sideView 明显以一种我不理解的奇怪方式影响着 mainView,所以我仍然尝试使用这个选项,但它没有产生任何区别。 - Bri Bri
抱歉,我误读了你的问题。如果它们是兄弟姐妹,我不知道你遇到了什么问题。 - Tricertops

0

我终于找到了一个解决方案,而且我觉得它相当巧妙。以下是可行的代码:

mainView.transform = CGAffineTransformMakeTranslation(400,0);
CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:@"transform.translation.x" ];
[move setFromValue:[NSNumber numberWithFloat:200]];
[move setToValue:[NSNumber numberWithFloat:400]];
[move setDuration:0.25];
move.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[[mainView layer] addAnimation:move forKey:@"transform.translation.x"];

sideView.center = CGPointMake(100, 230);
CABasicAnimation *sideMove = [CABasicAnimation animationWithKeyPath:@"transform.translation.x" ];
[sideMove setFromValue:[NSNumber numberWithFloat:-200]];
[sideMove setToValue:[NSNumber numberWithFloat:0]];
[sideMove setDuration:0.25];
sideMove.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[[sideView layer] addAnimation:sideMove forKey:@"transform.translation.x"];

首先,如果我没有设置mainView的变换,整个动画都不会起作用,动画完成后mainView也不会移动到任何地方。我尝试设置它的frame和center,但都没有任何效果。只有变换才有效。这个细节类似于使用animateWithDuration方法。

其次,这是让我最困惑的部分,为什么数字是这样的?出于某种原因,我需要将mainView向右偏移200个像素(即sideView的宽度)才能使它正确对齐。如果我不这样做,它会动画到它原来的位置,即使我将它的仿射变换从标识变换改为向右平移200个像素。

据我所知,sideView以某种奇怪的方式影响着mainView,尽管它们是直接位于我的视图控制器顶层视图下的同级元素,并且不应该具有任何层次关系。我猜测这与从xib加载sideView有关,但据我所知,我正在正确地执行这个操作。

希望这个解决方案对于发现自己处于类似情况的其他人有用,他们就不必像我一样进行繁琐的编程了。

此外,如果有人能够对所有这些提供解释,我将非常感激!我不喜欢编写我不理解的代码,我很想了解为什么会发生所有这些,以便将来避免这样的情况。

1
真正的问题是,为什么它没有简单地工作?如果您可以告诉我更多信息:您从哪里调用动画?您在代码和XIB中使用自动调整大小或自动布局吗? - Tricertops
2
哦,天啊,整个问题就在于我开启了自动布局。这不是我第一次犯这种错误了,但是直到你提到它之前,我都忘记了它。我刚刚在我的两个xib文件中关闭了它,突然间animateWithDuration完美地工作了。由于这个功能,我浪费了数小时的时间,而且没有任何迹象表明它是罪魁祸首。 - Bri Bri
是的,当使用自动布局时,您不直接修改框架。我没有尝试在自动布局下进行动画,但也许您可以对约束的“常量”进行动画处理。 - Tricertops
@GuyGizmo 非常感谢你找到了那个!在这里浪费了一个半小时! - glogic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接