I'm trying to create a customized NavigationViewController
where the Navigation bar is a swipeable bar at the top that controls the transitions (think UITabBarController
but with swipe gestures not buttons). Here is a quick mockup. I apologize for the crudeness
I have the header bar set up as a ScrollView. I have been able to successfully detect the scroll amount using the scrollViewDidScroll
method. So I have the header bar portion rigged up. I now need to implement the transition movement in the scrollViewDidScroll
method.
I have looked up the Apple Documentation on how to embed view controllers inside each other but it hasn't really helped explain how to do this. The documentation mentions calling the addChildViewController:
method and a bunch of other methods which are fine if I want to make the viewControllers disappear and reappear instantly, but in this scenario I'm finding hard to do it interactively.
Do I create a snapshot of the current VC and then move it? But then what exactly am I moving? In the picture for example, am I moving the entire RedVC's to the left? But then how do I get a snapshot of the BlueVC if it starts moving from outside the frame? What if I want to load in images asynchronously in the BlueVC? Will I have to use a placeholder snapshot with placeholders until the BlueVC snaps in place?
This is all becoming so convoluted... I've done stuff like this separately (snapshots, custom VC transitions, etc..) but I'm not comfortable enough in combining them all in a case like this. I'm sure I can hack up some way given enough time, but I want to learn what is the best, cleanest way.
I appreciate any help! Thanks.
Edit after accepting @MilanNosáľ's answer:
I ended up using his framework as linked in this repo. It's not interactive yet, but I can figure out the rest using what they've very graciously done for me. I wish I could post the full code here, but that's not very practical. The repo will remain up indefinitely for future SO travelers.
I'm gonna shamelessly advertise my own open-source project, in which I am dealing with similar tasks - InteractiveTransitioningContainer. It's goal was to prepare a framework for implementing custom containers that allow interactive transitions between its child controllers. While this may not be a direct answer to the question, I spent many hours try to provide the same environment for the child controllers as standard containers do - e.g., make sure their view(Will|Did)(A|Disa)ppear
callbacks are called in right order - I had to experiment with the UINavigationController
to analyze its behavior, etc.
So if nothing else, maybe you'll find some inspiration/knowledge there.
What you really needs is creating custom segue to move from the current VC to the destination VC and override perform method like that , in this code snippet current VC moves up and destination animates from bottom to top , feel free to change any way
override func perform() {
// Assign the source and destination views to local variables.
var firstVCView = self.sourceViewController.view as UIView!
var secondVCView = self.destinationViewController.view as UIView!
// Get the screen width and height.
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
// Specify the initial position of the destination view.
secondVCView.frame = CGRectMake(0.0, screenHeight, screenWidth, screenHeight)
// Access the app's key window and insert the destination view above the current (source) one.
let window = UIApplication.sharedApplication().keyWindow
window?.insertSubview(secondVCView, aboveSubview: firstVCView)
// Animate the transition.
UIView.animateWithDuration(0.4, animations: { () -> Void in
firstVCView.frame = CGRectOffset(firstVCView.frame, 0.0, -screenHeight)
secondVCView.frame = CGRectOffset(secondVCView.frame, 0.0, -screenHeight)
}) { (Finished) -> Void in
self.sourceViewController.presentViewController(self.destinationViewController as UIViewController,
animated: false,
completion: nil)
}
}
see more info is here custom-segue-animations
I initially had Milan's answer selected as the final answer to the question. But, after I tried working on it for the past few weeks, with a lot of help from him, we both agreed it was too difficult to integrate his framework into a format useable for this task. I'm now working on just using a UIScrollView
for the ViewControllers below, and let the HeaderView
above (the thing with the labels) control the ViewControllers' scroll view below.