Programmatically enumerate outgoing Segues for a UIViewController
This is an undocumented behaviour but
NSArray *segueTemplates = [self valueForKey:@"storyboardSegueTemplates"] ;
should return an array that includes all possible segue values that can be passed to performSegueWithIdentifier
.
Swift: programmatically enumerate outgoing segues from a UIVIewController
this valueForKey("storyboardSegueTemplates")
is UNDOCUMENTED property and UIStoryboardPresentationSegueTemplate
is UNDOCUMENTED class. Beware of rejection from App Store if you are uploading application to App Store.
If you want to use this in your in-house projects, use as following
for template in (valueForKey("storyboardSegueTemplates") as? [AnyObject])! {
if let identifier = template.valueForKey("identifier") as? String {
print("identifier - " + identifier)
}
else {
print("no identifier for \(template)")
}
}
Found from https://github.com/JaviSoto/iOS9-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIStoryboardSegueTemplate.h
Get list of all segues connected to a view
As I said in comment, in order to find which segue is missing, you can encapsulate the performSegue...
method of your UIViewController
into a try catch
block, if there is an exception thrown then one of your segue has been removed. (The one that tries to perform)
How to check if a view controller can perform a segue
As stated in the documentation:
Apps normally do not need to trigger segues directly.
Instead, you configure an object in Interface Builder associated with
the view controller, such as a control embedded in its view hierarchy,
to trigger the segue. However, you can call this method to trigger a
segue programmatically, perhaps in response to some action that cannot
be specified in the storyboard resource file. For example, you might
call it from a custom action handler used to process shake or
accelerometer events.The view controller that receives this message must have been loaded
from a storyboard. If the view controller does not have an associated
storyboard, perhaps because you allocated and initialized it yourself,
this method throws an exception.
That being said, when you trigger the segue
, normally it's because it's assumed that the UIViewController
will be able to respond to it with a specific segue's
identifier. I also agree with Dan F, you should try to avoid situations where an exception could be thrown. As the reason for you not to be able to do something like this:
if ([self canPerformSegueWithIdentifier:@"SegueID"])
[self performSegueWithIdentifier:@"SegueID"];
I am guessing that:
respondsToSelector:
only checks if you are able to handle that message in runtime. In this case you can, because the classUIViewController
is able to respond toperformSegueWithIdentifier:sender:
. To actually check if a method is able to handle a message with certain parameters, I guess it would be impossible, because in order to determine if it's possible it has to actually run it and when doing that theNSInvalidArgumentException
will rise.- To actually create what you suggested, it would be helpful to receive a list of segue's id that the
UIViewController
is associated with. From theUIViewController
documentation, I wasn't able to find anything that looks like that
As for now, I am guessing your best bet it's to keep going with the @try
@catch
@finally
.
Programmatically copy array to new view in Storyboard
It does not make sense to create your own instance of CustomerListViewController
here if you're using segues. The segue itself will create the view controller from the storyboard and the instance you have created here will do nothing.
Instead, just call performSegueWithIdentifier:sender:
here. Then implement the prepareForSegue:sender:
method like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"LoginSegue"]) {
CustomerListViewController *destinationController = (CustomerListViewController *)segue.destinationViewController;
[destinationController setValue:customerList.list];
}
}
UIViewController - alloc and init vs. instantiate?
[[MyObject alloc] init]
creates a new object. It's not retrieving an object from a Storyboard, just allocating memory for it and instantiating it.
instantiateViewControllerWithIdentifier:
creates a new view controller (if the identifier exists in the storyboard) and configures it according to how the view controller was configured object in the Storyboard file.
Both cases will create a new instance for each call.
If you have configured a view controller in the Storyboard (for example connected outlets, actions, etc.) and you want to retrieve it, you should read it from the Storyboard. If you would create a new instance (not from the Storyboard) it would not have this configuration.
Related Topics
Monitoring App Switching on Os X
Use Multiple Codingkeys for a Single Property
Realitykit - How to Set a Modelentity's Transparency
What Makes a Property a Computed Property in Swift
Core Data Predicate Not Working
Call External Function Using Watchkit Force Touch Menuitem
How to Generate a Binding for Each Array Element
Extending View with Extra Function Without Using Anyview
Animate Cell When Pressed Using Swift 3
Programmatically Disabling Screenshot in App
Why Does Swiftui Uihostingcontroller Have Extra Spacing
How to Draw a Cosine or Sine Curve in Swift
How to Call the More Specific Method of Overloading
Physicsbody: Could Not Create Physics Body
Adding Items to Array as a Dictionary Value
Opposite of _Conversion in Swift to Assign to a Value of a Different Type