0
votes

I'm using a simple custom segue from my UIViewController to a UINavigationController which holds UICollectionViewController as it's root view controller.

The transition works as expected, but i first see a black screen and only when the transition has ended i see the UICollectionViewController content.

Storyboard:

enter image description here

Segue:

enter image description here

This is the code for the custom segue:

- (void)perform {
    UIViewController *sourceViewController = self.sourceViewController;
    UINavigationController *destinationViewController = self.destinationViewController;


    [UIView animateWithDuration:0.25
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                         destinationViewController.topViewController.view.transform =
                         CGAffineTransformMakeTranslation(0, 0);
                         sourceViewController.view.transform =
                         CGAffineTransformMakeTranslation(-sourceViewController.view.frame.size.width, 0);
                     }
                     completion:^(BOOL finished){
                         [destinationViewController.topViewController.view removeFromSuperview]; // remove from temp super view
                         [sourceViewController presentViewController:destinationViewController animated:NO completion:NULL]; // present VC
                     }];
}

NOTE:

When i am running a simple show segue, the collection view is loaded as it should, No black screen.

Any idea what i'm doing wrong here?

2

2 Answers

2
votes

Ok let's go through your destination view controller because it appear to be black: You're doing a reference to your destination view controller:

UINavigationController *destinationViewController = self.destinationViewController;

Then you want to animate it with

destinationViewController.topViewController.view.transform = ...

So you operate on view that is not shown on the screen yet.

Then after animation you're doint this:

[destinationViewController.topViewController.view removeFromSuperview]; // remove from temp super view

So you're actually here removing UIViewController superview not "temp" superview!

So when you in the next step

[sourceViewController presentViewController:destinationViewController animated:NO completion:NULL]; // present VC

Doing that your destinationViewController has no view whatsoever, so it appear as black screen.

To fix it copy a view animate and remove when destination vc is loaded. I believe that you had exactly this in mind when I look at your code.

So the base idea is:

override func perform() {
        let sourceVC = self.source
        let destinationVC = self.destination
        let view : UIView = UIView()
        view.frame = CGRect(x: sourceVC.view.frame.size.width, y: 0, width: sourceVC.view.frame.size.width, height: sourceVC.view.frame.size.height)
        view.addSubview(destinationVC.view)
        sourceVC.view.addSubview(view)

        UIView.animate(withDuration: 2, animations: {
            sourceVC.view.transform =
                CGAffineTransform(translationX: -sourceVC.view.frame.size.width, y: 0);

        }) { completion in
            view.removeFromSuperview()
            sourceVC.present(destinationVC, animated: false, completion: nil)
        }
    }

Of course code will be different when u use autolayout yes or no... But you should get from it a basic idea.

enter image description here

-2
votes

when you commit your animation, you transform the view of current controller, resultly there left the window, or rootViewController which's view's backgroundcolor is black. it makes sense you see the 'black screen' for animation duration --- 0.25s