I have problems with transitionWithView
and animateWithDuration
. One of my animateWithDuration
blocks doesn't transition, it is a sudden change, and transitionWithView
does not temporarily disable user interaction. I have checked the docs and believe I am doing everything correctly, but obviously something is wrong. Here are the two blocks of code:
This is in my main View Controller ViewController
which has three container views/child view controllers. This block moves one of the container views, but does not block the user from other interactions in ViewController
while the transition is occurring.
[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
}];
This is in one of my container view controllers. The animation seems to have no effect as the text of the productTitleLabel
and productDescriptionTextView
changes suddenly as if the animation block does not exist.
- (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"]];
}
}
}
I think the problems are somewhat related as most of my animation and transition blocks don't work completely as expected. Thanks for any help.
Edit
What I am trying to accomplish is moving a container view in ViewController
and set the text and image properties of a label, text view, and image view; all of which are in the main view. The details of these properties are sent via the child view controller. The transitionWithView
is in a method called toggleFlavoredOiveOilsTableView
which is called in didSelectRowAtIndexPath
. I think the problem is that I am trying to call two different animation/transition blocks at the same time.
You can experience this behavior of two animations interfering with each other if one animation is done on subview of another view undergoing animation. Thus, if you perform transitionWithView:self.view
(i.e. on the main view) like your code snippet suggests, you can have problems. If you perform the two animations on distinct subviews, the problem may go away. In my original answer below, I:
Perform transitionWithView
on a subview that has the two UILabel
controls;
Put my view controller containment child views within a subview of the main view, and then the transitionFromViewController
is constrained to that subview.
When I put the two animated portions on distinct subviews, the animations can take place simultaneously without incident.
If you want to animate the changing of the contents of two text labels, you can:
[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];
Generally I'd use animateWithDuration
, but the text attribute is not an animatable property, so that's why I use transitionWithView
, making sure that I have a container for those text fields. But I've tried animating other controls using animateWithDuration
, while simultaneously animating the changing of the child controllers, and it works fine.
For transitioning the child view controllers, I use transitionFromViewController
to animate the swapping of the containers child controller's views (it's part of the Managing Child View Controllers in a Custom Container family of methods). In order to facilitate that process, I put a container view on my main view controller's view, and add the child controller's views as a subview of that container. That way, when I animate the transition of the child, the animations are nicely constrained to that container view.
So, here is some sample code to add a view controller to my container view, and then the code I use to transition between two child view controllers using a segmented button:
- (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];
}];
}
Bottom line, I have no problem animating both container child controllers and the fields in the parent controller. Perhaps I'm not understanding the problem you're describing. Or maybe there's something subtle about the differences in how we're animating. If you want, I've put this above code on github if you want to take a look.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With