Reputation: 4149
@objc(SEPushNoAnimationSegue)
class SEPushNoAnimationSegue: UIStoryboardSegue {
override func perform () {
self.sourceViewController.navigationController.pushViewController(self.destinationViewController, animated:false)
}
}
In the above code, I have 2 questions: 1). it has a compile error: 'UINavigationController!' does not have a member named 'pushViewController'
But in that class, it did has a pushViewController method.
2). I have to add the annotation: @objc(SEPushNoAnimationSegue), otherwise, in storyboard, it only recognize the random generated name, like, _tcxxxxSEPushNoAnimationSegue.
why these 2 issues happen here?
Upvotes: 15
Views: 17453
Reputation: 982
Swift 3.0:
import UIKit
class CustomNoAnimationSegue: UIStoryboardSegue {
override func perform() {
if let navigation = source.navigationController {
navigation.pushViewController(destination, animated: false)
}
}
}
Upvotes: 0
Reputation: 22236
UIStoryboardSegue has an irritating flaw: its sourceViewController and destinationViewController properties are typed as AnyObject!
(that's the case even in Objective-C (Id type)) and not as UIViewController
, as it should be.
That same flaw creates havoc in your perfect and simple code. Here's how to rewrite it in order to fix the compile errors:
@objc(SEPushNoAnimationSegue)
class SEPushNoAnimationSegue: UIStoryboardSegue {
override func perform () {
let src = self.sourceViewController as UIViewController
let dst = self.destinationViewController as UIViewController
src.navigationController.pushViewController(dst, animated:false)
}
}
NOTE: Apple fixed this thing in iOS 9. sourceViewController
and destinationViewController
are now correctly declared as UIViewController
.
The Swift compiler stores its symbols using its own name mangling, and good ol' Objective-C does not recognize it in Xcode. Using an explicit @obj()
solves the issue.
Upvotes: 35
Reputation: 11
Even Better:
import UIKit
class CustomSegue: UIStoryboardSegue {
override func perform() {
self.sourceViewController.presentViewController(self.destinationViewController as UIViewController, animated: false, completion: nil)
}
}
Upvotes: 1
Reputation: 5463
This works fine for me
@objc(SEPushNoAnimationSegue) class SEPushNoAnimationSegue: UIStoryboardSegue {
override func perform() {
let sourceViewController = self.sourceViewController as UIViewController
let destinationViewController = self.destinationViewController as UIViewController
sourceViewController.presentViewController(destinationViewController, animated: true, completion: nil)
}
}
Upvotes: 5