Reputation: 2640
I am using normal storyboarding and push segues in xcode, but I want to have segues that just appear the next view, not slide the next view (as in when you use a tab bar and the next view just appears).
Is there a nice simple way to have normal push segues just "appear" and not "slide", without needing to add custom segues?
Everything is working completely fine, I just want to remove that slide animation between the views.
Upvotes: 90
Views: 37784
Reputation: 4321
Ian's answer works great!
Here's a Swift version of the Segue, if anyone needs:
UPDATED FOR SWIFT 5, MAY 2020
PushNoAnimationSegue.swift
import UIKit
/// Move to the next screen without an animation
class PushNoAnimationSegue: UIStoryboardSegue {
override func perform() {
if let navigation = source.navigationController {
navigation.pushViewController(destination as UIViewController, animated: false)
}
}
Upvotes: 35
Reputation: 467
PUSH WITHOUT ANIMATION : Swift Here is what worked for me.
import ObjectiveC
private var AssociatedObjectHandle: UInt8 = 0
extension UIViewController {
var isAnimationRequired:Bool {
get {
return (objc_getAssociatedObject(self, &AssociatedObjectHandle) as? Bool) ?? true
}
set {
objc_setAssociatedObject(self, &AssociatedObjectHandle, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
-------------------- SilencePushSegue --------------------
class SilencePushSegue: UIStoryboardSegue {
override func perform() {
if self.source.isAnimationRequired == false {
self.source.navigationController?.pushViewController(self.destination, animated: false)
}else{
self.source.navigationController?.pushViewController(self.destination, animated: true)
}
}
}
Usage : Set the segue class from storyboard as shown in picture. set the isAnimationRequired from your viewcontroller to false from where you want to call performSegue, when you want to push segue without animation and set back to true after calling self.performSegue. Best of luck....
DispatchQueue.main.async {
self.isAnimationRequired = false
self.performSegue(withIdentifier: "showAllOrders", sender: self);
self.isAnimationRequired = true
}
Upvotes: 0
Reputation: 7558
I was able to do this by creating a custom segue (based on this link).
PushNoAnimationSegue
(or whatever you decided to call it).import UIKit
/*
Move to the next screen without an animation.
*/
class PushNoAnimationSegue: UIStoryboardSegue {
override func perform() {
self.source.navigationController?.pushViewController(self.destination, animated: false)
}
}
PushNoAnimationSegue.h
#import <UIKit/UIKit.h>
/*
Move to the next screen without an animation.
*/
@interface PushNoAnimationSegue : UIStoryboardSegue
@end
PushNoAnimationSegue.m
#import "PushNoAnimationSegue.h"
@implementation PushNoAnimationSegue
- (void)perform {
[self.sourceViewController.navigationController pushViewController:self.destinationViewController animated:NO];
}
@end
Upvotes: 143
Reputation: 1069
I'm using Visual Studio w/ Xamarin, and the designer doesn't provide the "Animates" checkmark in dtochetto's answer.
Note that the XCode designer will apply the following attribute to the segue element in the .storyboard file: animates="NO"
I manually edited the .storyboard file and added animates="NO" to the segue element(s), and it worked for me.
Example:
<segue id="1234" destination="ZB0-vP-ctU" kind="modal" modalTransitionStyle="crossDissolve" animates="NO" identifier="screen1ToScreen2"/>
Upvotes: 0
Reputation: 151
answer using Swift3 -
for "push" segue:
class PushNoAnimationSegue: UIStoryboardSegue
{
override func perform()
{
source.navigationController?.pushViewController(destination, animated: false)
}
}
for "modal" segue:
class ModalNoAnimationSegue: UIStoryboardSegue
{
override func perform() {
self.source.present(destination, animated: false, completion: nil)
}
}
Upvotes: 2
Reputation: 87
For me, the easiest way to do so is :
UIView.performWithoutAnimation {
self.performSegueWithIdentifier("yourSegueIdentifier", sender: nil)
}
Available from iOS 7.0
Upvotes: 0
Reputation: 9864
Just set animated
false on UINavigationController.pushViewController
in Swift
self.navigationController!.pushViewController(viewController, animated: false)
Upvotes: 0
Reputation: 53
For anyone using Xamarin iOS your custom segue class needs to look like this:
[Register ("PushNoAnimationSegue")]
public class PushNoAnimationSegue : UIStoryboardSegue
{
public PushNoAnimationSegue(IntPtr handle) : base (handle)
{
}
public override void Perform ()
{
SourceViewController.NavigationController.PushViewController (DestinationViewController, false);
}
}
Don't forget you still need set a custom segue in your story board and set the class to the PushNoAnimationSegue class.
Upvotes: 1
Reputation: 451
Here's the Swift version adapted to modally present a ViewController without animation:
import UIKit
/// Present the next screen without an animation.
class ModalNoAnimationSegue: UIStoryboardSegue {
override func perform() {
self.sourceViewController.presentViewController(
self.destinationViewController as! UIViewController,
animated: false,
completion: nil)
}
}
Upvotes: 4
Reputation: 2640
I have now managed to do this using the following code:
CreditsViewController *creditspage = [self.storyboard instantiateViewControllerWithIdentifier:@"Credits"];
[UIView beginAnimations:@"flipping view" context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:YES];
[self.navigationController pushViewController:creditspage animated:NO];
[UIView commitAnimations];
Hope this helps someone else!
Upvotes: 6