我在使用 transitionWithView
和 animateWithDuration
时遇到问题。我的一个 animateWithDuration
block 没有过渡,这是一个突然的变化,并且 transitionWithView
不会暂时禁用用户交互。我检查了文档并相信我做的一切都是正确的,但显然有些地方不对劲。这是两个代码块:
这是在我的主视图 Controller ViewController
中,它具有三个容器 View / subview Controller 。此 block 移动其中一个容器 View ,但不会在发生转换时阻止用户在 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
}];
这是在我的一个容器 View Controller 中。动画似乎没有效果,因为 productTitleLabel
和 productDescriptionTextView
的文本突然发生变化,就好像动画 block 不存在一样。
- (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"]];
}
}
}
我认为这些问题在某种程度上是相关的,因为我的大部分动画和过渡 block 都没有完全按预期工作。感谢您的帮助。
编辑
我想要完成的是在 ViewController
中移动容器 View ,并设置标签、 TextView 和 ImageView 的文本和图像属性;所有这些都在主视图中。这些属性的详细信息通过 subview Controller 发送。 transitionWithView
位于名为 toggleFlavoredOiveOilsTableView
的方法中,该方法在 didSelectRowAtIndexPath
中调用。我认为问题在于我试图同时调用两个不同的动画/过渡 block 。
最佳答案
如果一个动画是在另一个正在进行动画的 View 的 subview 上完成的,您可能会遇到两个动画相互干扰的行为。因此,如果您像您的代码片段建议的那样执行 transitionWithView:self.view
(即在主视图上),您可能会遇到问题。如果您在不同的 subview 上执行这两个动画,问题可能会消失。在我下面的原始答案中,我:
在具有两个
UILabel
控件的 subview 上执行transitionWithView
;将包含 subview 的 View Controller 放在主视图的 subview 中,然后将
transitionFromViewController
约束到该 subview 。
当我将两个动画部分放在不同的 subview 上时,动画可以同时发生而不会发生意外。
如果你想动画改变两个文本标签的内容,你可以:
[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
为其他控件设置动画,同时为子 Controller 的变化设置动画,效果很好。
为了转换 subview Controller ,我使用 transitionFromViewController
为容器子 Controller View 的交换设置动画(它是 Managing Child View Controllers in a Custom Container 方法系列的一部分)。为了促进该过程,我在主视图 Controller 的 View 上放置了一个容器 View ,并将子 Controller 的 View 添加为该容器的 subview 。这样,当我为 child 的过渡设置动画时,动画很好地限制在该容器 View 中。
所以,这里有一些示例代码,用于将 View Controller 添加到我的容器 View ,然后是我使用分段按钮在两个 subview Controller 之间转换的代码:
- (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];
}];
}
最重要的是,我可以毫无问题地为容器子 Controller 和父 Controller 中的字段设置动画。也许我不理解你描述的问题。或者我们制作动画的方式可能存在一些微妙的差异。如果你愿意,我已经放了this above code在github上,如果你想看一看。
关于iphone - transitionWithView 和 animateWithDuration 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13885603/