0
votes

I have a container view controller that controllers the transition between two child view controllers. The animation and transition is working as I intend. I click my button and the view controller in my container is swapped with the other child view controller with a nice custom animation.

However, If I click my button while my transition animation is in progress it will screw up presentation of the view controllers.

How do I allow my swapping of view controllers method to work even when the animation between swapping is in progress?

Here is my code for swapping VCs in a container view controller.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:SegueIdentifierFirst])
    {
        if (self.childViewControllers.count > 0) {
            [self swapFromViewController:[self.childViewControllers objectAtIndex:0] toViewController:segue.destinationViewController];
        }
        else {
            [self addChildViewController:segue.destinationViewController];
            ((UIViewController *)segue.destinationViewController).view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
            [self.view addSubview:((UIViewController *)segue.destinationViewController).view];
            [segue.destinationViewController didMoveToParentViewController:self];
        }
    }
    else if ([segue.identifier isEqualToString:SegueIdentifierSecond])
    {
        [self swapFromViewController:[self.childViewControllers objectAtIndex:0] toViewController:segue.destinationViewController];
    }
}

- (void)swapFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController
{
    toViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    [fromViewController willMoveToParentViewController:nil];
    [self addChildViewController:toViewController];

    float width = self.view.frame.size.width;
    float height = self.view.frame.size.height;
    toViewController.view.frame = CGRectMake(0, 560, width, height);
    [self transitionFromViewController:fromViewController toViewController:toViewController duration:.2 options:UIViewAnimationOptionCurveLinear animations:^{
        fromViewController.view.frame = CGRectMake(0, 560, width, height);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:.2 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            toViewController.view.frame = CGRectMake(0, 0, width, height);
        } completion:^(BOOL finished) {
            [fromViewController removeFromParentViewController];
            [toViewController didMoveToParentViewController:self];
        }];
    }];
}

- (void)swapViewControllers
{
    self.currentSegueIdentifier = ([self.currentSegueIdentifier  isEqual: SegueIdentifierFirst]) ? SegueIdentifierSecond : SegueIdentifierFirst;
    [self performSegueWithIdentifier:self.currentSegueIdentifier sender:nil];
}

Here is the button used to swap in my main view controller.

- (IBAction)playlistsButtonPressed:(UIButton *)sender
{
    [self.containerViewController swapViewControllers];

    if ([self.playlistsButton.titleLabel.text isEqualToString:@"PLAYLISTS"]) {
        [self.playlistsButton setTitle:@"SEARCH" forState:UIControlStateNormal];
    }
    else{
        [self.playlistsButton setTitle:@"PLAYLISTS" forState:UIControlStateNormal];
    }
}

Is this even possible? Or am i going to have to disable/enable my button while animation is in progress? If so, how should I go about doing this?

2

2 Answers

0
votes

This code seems to fix the problem. Not sure if it is the right way to go about fixing this though.

I changed where I am removing the fromViewController from parent view controller to the start of the animation block.

 [self transitionFromViewController:fromViewController toViewController:toViewController duration:.2 options:UIViewAnimationOptionCurveLinear animations:^{
        [fromViewController removeFromParentViewController];
        fromViewController.view.frame = CGRectMake(0, 560, width, height);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:.2 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            toViewController.view.frame = CGRectMake(0, 0, width, height);
        } completion:^(BOOL finished) {
            [toViewController didMoveToParentViewController:self];
        }];
    }];
0
votes

Better to set:

   - (void)swapViewControllers
{

  if (self.transitionInProgress) {
    return;
}

  // YOUR CODE

}

Where transitionInProgress is a BOOLEAN value, which is set to NO in the begining