This code works fine to make my custom segue transition with a downwards animation. How would I make the animation look as if it is transitioning to the left or right?
Also - I am using a UISwipeGestureRecognizer to trigger the segue. It works fine except that the segue occurs as soon as I do the smallest swipe. How would I allow the segue to not occur untill a user has lifted their finger off or atleast done a larger swipe. Would I need to use a scrollView for this?
Below is my code for my UISwipeGestureRecognizer.
override func viewDidLoad() {
var swipeGestureRecognizer: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "showSecondViewController")
swipeGestureRecognizer.direction = UISwipeGestureRecognizerDirection.Up
self.view.addGestureRecognizer(swipeGestureRecognizer)
}
The code below is my animation code
class FirstCustomSegue: UIStoryboardSegue {
override func perform() {
// 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.5, 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)
}
}
}
Animation Direction
You will simply need to change the initial and destination frames. Currently the secondVCView
's initial frame's X,Y origin 0.0
, screenHeight
, meaning it sits just below the bottom of the screen. If you want it to appear from the right you would need to change it to screenWidth
, 0.0
.
Then the destination frame of firstVCView
would change so the origin is -screenWidth
, 0.0
and the destination frame of secondVCView
would change so the origin is 0.0
, 0.0
override func perform() {
// Specify the initial position of the destination view.
secondVCView.frame = CGRectMake(screenWidth, 0.0, 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.5, animations: { () -> Void in
firstVCView.frame = CGRectOffset(firstVCView.frame, -screenWidth, 0.0)
secondVCView.frame = CGRectOffset(secondVCView.frame, -screenWidth, 0.0)
}) { (Finished) -> Void in
self.sourceViewController.presentViewController(self.destinationViewController as! UIViewController,
animated: false,
completion: nil)
}
}
}
Delayed swipe
Modify your showSecondViewController
method to accept a UISwipeGestureRecognizer
parameter and inspect it's state
property. If you want to trigger the segue when the user has lifted their finger trigger the segue when the state
is UIGestureRecognizerStateEnded
.
If you want more fine grained control such as when they have swiped a certain distance you will need to check the state for UIGestureRecognizerStateChanged
and monitor the location of the touch. I'll leave that as an exercise for the reader as there are plenty of examples a quick Google search away :)