1
votes

Attempting to write a custom segue where the source view is scaled out, while changing the alpha of the destination to fade the destination in. The destination is a MKMapView, so I want it updating as the fade occurs.
With what I've tried I end up with the source and designation scaling out simultaneously, and I can't get just the source view to scale out.

    class Map_Segue: UIStoryboardSegue {

    override func perform()
    {
        var sourceViewController      : UIViewController = self.sourceViewController as UIViewController
        var destinationViewController : UIViewController = self.destinationViewController as UIViewController           
        destinationViewController.view.alpha = 0            sourceViewController.addChildViewController(destinationViewController)            sourceViewController.view.addSubview(destinationViewController.view)            
        UIView.animateWithDuration(2.0,delay:1.0,options: UIViewAnimationOptions.CurveEaseInOut, // delay of 1 second for aesthetics
            animations:
            {
                sourceViewController.view.transform = CGAffineTransformScale(sourceViewController.view.transform, 100.0, 100.0);
                destinationViewController.view.alpha = 1;
            },
            completion:
            {  (finished:Bool)->Void in
                destinationViewController.didMoveToParentViewController(sourceViewController);
            }
        )
    }
}

I've tried autoresizesSubviews=false, but that doesn't seem to do anything.

I've tried setting the destination transform in the animation to be 1/100 (and set the options to UIViewAnimationOptions.CurveLinear which has the final result correct, but the transition effect is wrong (map in the background scaled up then down again) I'm sure this should be easy, and I'm missing a trick as I'm new to this. Anyone got any ideas?

Update:

I've found that (somewhat obviously) I should use sourceViewController.view.superview?.insertSubview( destinationViewController.view, atIndex:0) to insert it alongside the original source view, rather than as a child of it, that way, obviously, the transform is independent, not with respect to the views parent (which it will be as a subview). The problem then is swapping to the new view. Using the method I had, viewWillAppear and similar are not called, and the changing over the views does not work. If I call presentViewController, then we get a glitch when viewWillAppear is called.

Solution so far

Forget using custom segues. Followed the suggestion and placed a UIImageView on top of the map view, and had a beautiful animating fade in about 5 minutes of coding.

1
I think an image would clarify what you are trying to accomplish. One thing I see here: You add the destinationView as a child to the sourceView and then you perform the animation on the sourceView, which of course affects the destinationView, too...? - zisoft
yes, that's the problem - how do I prevent the source view transform from affecting the destination? Is there a different way to do this, whilst having both views active? Will see if I can create a visual of what I'm after. Thanks. - xyzDave
What about a viewController wich holds 2 containerViews, the sourceViewController and the destinationViewController, and perform the animations on these two viewControllers? Just a thought... - zisoft
Thats a thought - will try that. Was hoping to use seques so I could mix and match a bit. An example of the look is similar to the twitter bird logo when you start the twitter app - is zooms out and reveals what is behind (though rather than using a cutout and alpha, I'm after a fade). - xyzDave
I finally went for your suggestion of two views - a UIImageView on top of the MKMapView, and faded out the animating UIImageView to give the desired effect. A lot easier than custom segues. Thanks for the suggetion - xyzDave

1 Answers

0
votes

I think you are a bit confused with parent and child view controllers etc. It is sufficient to temporarily add the second view controller's view to the first one, perform the transitions and then clean up.

I tested the following in a simple sample project. Note that I am adding the second view controller's view to the window rather than the first view controller's view because otherwise it would also get scaled up.

override func perform() {
    let first = self.sourceViewController as ViewController
    let second = self.destinationViewController as ViewController

    second.view.alpha = 0
    first.view.window!.addSubview(second.view)

    UIView.animateWithDuration(2.0, delay: 0.0, 
     options: .CurveEaseInOut, animations: { () -> Void in
        first.view.transform = CGAffineTransformMakeScale(100.0, 100.0)
        second.view.alpha = 1.0
     })
     { (finished: Bool) -> Void in
        second.view.removeFromSuperview()
        first.presentViewController(second, animated: false, completion: nil)
    }
}