如何检查一个视图控制器是否可以执行一个segue

这可能是一个非常简单的问题,但没有得到任何结果时,search它,所以这里是…

我正在试图找出一种方法来检查某个视图控制器是否可以在调用performSegueWithIdentifier:方法之前使用标识符XYZ执行segue。

有些东西是:

 if ([self canPerformSegueWithIdentifier:@"SegueID"]) [self performSegueWithIdentifier:@"SegueID"]; 

可能?

正如文件中所述:

应用程序通常不需要直接触发赛格。 而是在与视图控制器相关联的Interface Builder中configuration一个对象,例如embedded其视图层次结构中的控件,以触发segue。 但是,您可以调用此方法以编程方式触发segue,也许可以响应故事板资源文件中无法指定的某些操作。 例如,您可以从用于处理摇晃或加速度计事件的自定义操作处理程序中调用它。

接收此消息的视图控制器必须已从故事板加载。 如果视图控制器没有关联的故事板,也许是因为您自己分配并初始化了它,则此方法会引发exception。

这就是说,当你触发segue ,通常是因为它假定UIViewController能够用一个特定的segue's标识符来响应它。 我也同意丹F,你应该尽量避免可能抛出exception的情况。 作为你不能这样做的原因:

 if ([self canPerformSegueWithIdentifier:@"SegueID"]) [self performSegueWithIdentifier:@"SegueID"]; 

我猜测:

  1. respondsToSelector:仅检查您是否能够在运行时处理该消息。 在这种情况下,你可以,因为UIViewController类可以响应performSegueWithIdentifier:sender: 要真正检查一个方法是否能够处理带有特定参数的消息,我想这是不可能的,因为为了确定是否有可能实际运行它,当这样做时, NSInvalidArgumentException将会上升。
  2. 要真正地创build你的build议,接收UIViewController所关联的segue的id列表会很有帮助。 从UIViewController 文档 ,我无法find任何看起来像这样的东西

至于现在,我猜你最好的select就是继续使用@try @catch @finally

为了检查segue是否存在,我简单地用try-and-catch块来包围这个调用。 请参阅下面的代码示例:

 @try { [self performSegueWithIdentifier:[dictionary valueForKey:@"segue"] sender:self]; } @catch (NSException *exception) { NSLog(@"Segue not found: %@", exception); } 

希望这可以帮助。

 - (BOOL)canPerformSegueWithIdentifier:(NSString *)identifier { NSArray *segueTemplates = [self valueForKey:@"storyboardSegueTemplates"]; NSArray *filteredArray = [segueTemplates filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"identifier = %@", identifier]]; return filteredArray.count>0; } 

这是一个更正确的 Swift方法来检查是否存在一个segue:

 extension UIViewController { func canPerformSegue(id: String) -> Bool { let segues = self.valueForKey("storyboardSegueTemplates") as? [NSObject] let filtered = segues?.filter({ $0.valueForKey("identifier") as? String == id }) return (filtered?.count > 0) ?? false } // Just so you dont have to check all the time func performSegue(id: String, sender: AnyObject?) -> Bool { if canPerformSegue(id) { self.performSegueWithIdentifier(id, sender: sender) return true } return false } } // 1 if canPerformSegue("test") { self.performSegueWithIdentifier("test", sender: nil) } // 2 performSegue("test", sender: nil) 

你可以覆盖 – (BOOL)shouldPerformSegueWithIdentifier:sender:方法,并在那里做你的逻辑。

 - (BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender { if ([identifier isEqualToString:@"someSegue"]) { if (!canIPerformSegue) { return NO; } } return YES; } 

希望这可以帮助。

迅速的版本的叶夫根尼·米哈伊洛夫的答案,这为我工作:

我重用了两个视图的控制器。 这有助于我重用代码。

 if(canPerformSegueWithIdentifier("segueFoo")) { self.performSegueWithIdentifier("segueFoo", sender: nil) } else { self.performSegueWithIdentifier("segueBar", sender: nil) } func canPerformSegueWithIdentifier(identifier: NSString) -> Bool { let templates:NSArray = self.valueForKey("storyboardSegueTemplates") as! NSArray let predicate:NSPredicate = NSPredicate(format: "identifier=%@", identifier) let filteredtemplates = templates.filteredArrayUsingPredicate(predicate) return (filteredtemplates.count>0) } 

没有办法检查使用标准函数,你可以做的是子类UIStoryboardSegue并将信息存储在source视图控制器(它传递给构造函数)。 在界面构build器中,select“Custom”作为seguetypes,键入你的segue的类名,然后你的构造函数将被调用,每个segue实例化,你可以查询存储的数据是否存在。

您还必须根据所需的过渡types,重写perform方法来调用[source presentModalViewController:destination animated:YES][source pushViewController:destination animated:YES]