Swift: Programmatically Enumerate Outgoing Segues from a Uiviewcontroller

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:

  1. respondsToSelector: only checks if you are able to handle that message in runtime. In this case you can, because the class UIViewController is able to respond to performSegueWithIdentifier: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 the NSInvalidArgumentException will rise.
  2. 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 the UIViewController 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



Leave a reply



Submit