transitionWithView 和 animateWithDuration 的问题
Posted
技术标签:
【中文标题】transitionWithView 和 animateWithDuration 的问题【英文标题】:Problems with transitionWithView and animateWithDuration 【发布时间】:2012-12-14 20:13:26 【问题描述】:transitionWithView
和 animateWithDuration
有问题。我的一个animateWithDuration
块没有过渡,这是一个突然的变化,transitionWithView
不会暂时禁用用户交互。我检查了文档并相信我做的一切都是正确的,但显然有问题。下面是两段代码:
这是在我的主视图控制器ViewController
中,它具有三个容器视图/子视图控制器。此块移动容器视图之一,但不会在转换发生时阻止用户与ViewController
中的其他交互。
[UIView transitionWithView:self.view duration:0.5 options:UIViewAnimationOptionCurveEaseOut animations:^
CGRect frame = _containerView.frame;
frame.origin.y = self.view.frame.size.height - _containerView.frame.size.height;
_containerView.frame = frame;
completion:^(BOOL finished)
// do something
];
这是在我的一个容器视图控制器中。动画似乎没有效果,productTitleLabel
和 productDescriptionTextView
的文字突然变化,好像动画块不存在一样。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
[self.viewController toggleFlavoredOliveOilsTableView];
if (indexPath.row > 0)
NSDictionary *selectedCellDict = [[_flavoredOliveOilsDict objectForKey:@"Unflavored Olive Oils"] objectAtIndex:indexPath.row - 1];
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^
self.viewController.productTitleLabel.text = [_flavoredOliveOilsTableView cellForRowAtIndexPath:indexPath].textLabel.text;
self.viewController.productDescriptionTextView.text = [selectedCellDict objectForKey:@"Description"];
completion:nil];
if (indexPath.row == 1)
[self.viewController setProductDescriptionTextViewFrameForInformationTab];
else
[self.viewController setProductDescriptionTextViewFrameForNonInformationTab];
//self.viewController.productImageView.image = [UIImage imageNamed:[selectedCellDict objectForKey:@"Image"]];
我认为这些问题有些相关,因为我的大多数动画和过渡块都不能完全按预期工作。感谢您的帮助。
编辑
我想要完成的是在ViewController
中移动一个容器视图,并设置标签、文本视图和图像视图的文本和图像属性;所有这些都在主视图中。这些属性的详细信息通过子视图控制器发送。 transitionWithView
在一个名为toggleFlavoredOiveOilsTableView
的方法中,该方法在didSelectRowAtIndexPath
中调用。我认为问题在于我试图同时调用两个不同的动画/过渡块。
【问题讨论】:
【参考方案1】:如果一个动画是在另一个正在进行动画的视图的子视图上完成的,您可以体验到两个动画相互干扰的这种行为。因此,如果您像您的代码 sn-p 建议的那样执行transitionWithView:self.view
(即在主视图上),您可能会遇到问题。如果您在不同的子视图上执行这两个动画,问题可能会消失。在下面的原始答案中,我:
在具有两个 UILabel
控件的子视图上执行 transitionWithView
;
将我的视图控制器包含子视图放在主视图的子视图中,然后transitionFromViewController
被约束到该子视图。
当我将两个动画部分放在不同的子视图上时,动画可以同时发生而不会发生意外。
如果你想动画两个文本标签内容的变化,你可以:
[UIView transitionWithView:self.viewController.textLabelsContainerView
duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^
self.viewController.productTitleLabel.text = [_flavoredOliveOilsTableView cellForRowAtIndexPath:indexPath].textLabel.text;
self.viewController.productDescriptionTextView.text = [selectedCellDict objectForKey:@"Description"];
completion:nil];
通常我会使用animateWithDuration
,但文本属性不是可动画属性,所以这就是我使用transitionWithView
的原因,确保我有一个用于这些文本字段的容器。但我尝试使用animateWithDuration
为其他控件设置动画,同时为子控制器的变化设置动画,效果很好。
为了转换子视图控制器,我使用transitionFromViewController
为容器子控制器视图的交换设置动画(它是Managing Child View Controllers in a Custom Container 系列方法的一部分)。为了促进该过程,我在主视图控制器的视图上放置了一个容器视图,并将子控制器的视图添加为该容器的子视图。这样,当我为孩子的过渡设置动画时,动画会很好地限制在该容器视图中。
所以,这里是一些示例代码,用于将视图控制器添加到我的容器视图中,然后是我使用分段按钮在两个子视图控制器之间转换的代码:
- (void)addFirstChild
UIViewController *child = [self.storyboard instantiateViewControllerWithIdentifier:@"Stooge"];
[self addChildViewController:child];
child.view.frame = self.bottomContainerView.bounds;
[self.bottomContainerView addSubview:child.view];
[child didMoveToParentViewController:self];
- (void)changedChild
UIViewController *oldController = [self.childViewControllers lastObject];
UIViewController *newController;
if (self.segmentedControl.selectedSegmentIndex == 0)
newController = [self.storyboard instantiateViewControllerWithIdentifier:@"Stooge"];
else
newController = [self.storyboard instantiateViewControllerWithIdentifier:@"Marx"];
[oldController willMoveToParentViewController:nil];
[self addChildViewController:newController];
// start off screen below
CGRect startFrame = self.bottomContainerView.bounds;
startFrame.origin.y += startFrame.size.height;
// end up where it's supposed to be, right in the container
newController.view.frame = startFrame;
[self transitionFromViewController:oldController
toViewController:newController
duration:0.5
options:0
animations:^
newController.view.frame = self.bottomContainerView.bounds;
completion:^(BOOL finished)
[oldController removeFromParentViewController];
[newController didMoveToParentViewController:self];
];
底线,我对容器子控制器和父控制器中的字段进行动画处理都没有问题。也许我不理解你描述的问题。或者,我们制作动画的方式可能存在一些微妙的差异。如果你想看的话,我已经把this above code放到了github上。
【讨论】:
如果您想同时为两个标签设置动画,请将两个标签放在各自的标签容器视图中,然后将其用作transitionWithView
的第一个参数。
我的其中一个现在部分工作正常。是不是不能结合animateWithDuration
和UIViewAnimationOptionTransitions
或结合transitionWithView
和UIViewAnimationOptions
(非过渡)?似乎当我拥有这些时,它们不起作用,但如果我使用带有transitionWithView
的过渡选项,它确实有效,动画也是如此。我已阅读文档,似乎可以将所有文档组合在一起,但对我没有用。
请查看修改后的问题。谢谢
我在 github 上看到了你的代码,如果我分别调用它们,我可以让这两个动画工作。我想要的是同时具有交叉溶解动画和帧更改以及曲线缓出选项。现在,如果我同时调用它们,交叉溶解工作,但帧更改挂起,直到交叉溶解完成,然后帧更改没有动画。也许这是一个更清晰的解释。
顺便说一下,@MusicMathTech,请确保您的transitionWithView
没有使用 self.view
作为目标。你真的希望你的标签在你的主视图控制器的容器子视图上。同样,当您第一次执行第一个容器子控制器视图的 addSubview
时,请确保您没有将其添加到主 self.view
,而是您有一些容器子视图要添加到.这应该最大限度地减少动画之间的意外交互。如果我将 transitionWithView
更改为使用 self.view
,我会看到您描述的行为。以上是关于transitionWithView 和 animateWithDuration 的问题的主要内容,如果未能解决你的问题,请参考以下文章
使用动画块之外的更改时,UIView transitionWithView 是平滑的
UIView transitionWithView 不起作用
在 Xamarin 中使用 transitionWithView 设置 UIView.Hidden 属性时淡化动画