我试图在我的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的动画就开始工作了。
有谁知道怎么回事吗?从我读过的所有搜索和文档来看,我所做的应该没问题。我原本以为这只是一个简单的动画,结果却让我沮丧了好几个小时。任何帮助将非常感激!
编辑:根据郭鲁川的建议,我尝试了两个uiview的不同属性动画化。大多数都得到了相同的结果,尽管将它们的转换属性动画化几乎都有效。在那种情况下,两个uiview都动画了,但是mainView做了错误的事情:它的动画在不同的位置开始,在错误的地方结束。它看起来像是在执行我指示它做的转换,但从向量计算中表示的这个位置开始:starting_point - 0.5 * total_translation
表示结束于:
starting_point + 0.5 * total_translation
然而,sideView的动画是正确的。
这太烦人了。我没有意识到以这种方式在iOS上执行动画是如此糟糕。我要尝试的下一件事是使用CABasicAnimation,虽然我不高兴,我不得不诉诸于尝试这样一个低级API的东西这么简单。
我遇到过和你一样的问题。
当我同时设置2个视图相同属性(如frame
或transform
)时,在UIView animation block
中,它不会为我所期望的工作。
所以,我设置了一个视图frame
并设置了另一个视图transform
,然后它工作得很好,但我不知道为什么会这样。
我想它会很适合你的。
sideView.hidden = NO;
[UIView animateWithDuration:0.25f
animations:^{
mainView.frame = CGRectMake(200, 0, 320, 460);
sideView.transform = CGAffineTransformMakeTranslation(200,0);
}];
我认为你可以制作2个CABasicAnimation
,然后将它们添加到CAAnimationGroup
中。它也可以为你工作
问题是我为我的xib文件打开了自动调整大小。当我关闭它时,我的原始动画代码就可以完美地工作了。
如果sideView
是mainView
的子视图,则使用以下动画方法:
+animateWithDuration:delay:options:animations:completion:
与选择:UIViewAnimationOptionAllowAnimatedContent
我终于找到了一个解决方案,我认为这是相当可恶的。下面是有效的代码:
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不会在动画完成后移动到任何地方。我试着设置它的框架和中心,但都没有效果。只有变换有效。这个细节类似于使用animateWithDuration方法。
第二,这是最让我困惑的部分,为什么这些数字是这样的?出于某种原因,我需要将mainView向右偏移200个像素(sideView的宽度),以便使其正确对齐。如果我不这样做,它将动画到它原来的位置,即使我将它的仿射变换从恒等变换改为向右平移200像素。
据我所知,sideView以某种奇怪的方式影响着mainView,即使它们是兄弟直接在我的视图控制器的顶层视图下,并且不应该有任何层次关系。我猜这与从xib加载sideView有关,但据我所知,我这样做是正确的。
希望这个解决方案对那些发现自己处于类似情况的人有用,并且他们不必做我刚刚做的同样烦人的死鸡编程。
还有,如果有人能解释一下这一切,我将非常感激!我不喜欢编写我不理解的代码,我很想知道为什么会发生这样的事情,这样我就可以避免以后出现类似的情况。