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

Rog*_*Rog 35 objective-c ios ios5 uistoryboardsegue

这可能是一个非常简单的问题,但在搜索时没有产生任何结果,所以这里是......

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

有点像:

if ([self canPerformSegueWithIdentifier:@"SegueID"])
    [self performSegueWithIdentifier:@"SegueID"];
Run Code Online (Sandbox Code Playgroud)

可能?

Mic*_*ell 24

为了检查segue是否存在,我只是使用try-and-catch块来包围调用.请参阅下面的代码示例:

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

希望这可以帮助.

  • 您可能会在ARC下出现内存泄漏,因为它在异常后不会清理. (2认同)

Evg*_*lov 14

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

  • 谢谢这是很好的知道(尽管它是无证件的行为). (3认同)

Arb*_*tur 13

这篇文章已经针对Swift 4进行了更新.


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

extension UIViewController {
func canPerformSegue(withIdentifier id: String) -> Bool {
        guard let segues = self.value(forKey: "storyboardSegueTemplates") as? [NSObject] else { return false }
        return segues.first { $0.value(forKey: "identifier") as? String == id } != nil
    }

    /// Performs segue with passed identifier, if self can perform it.
    func performSegueIfPossible(id: String?, sender: AnyObject? = nil) {
        guard let id = id, canPerformSegue(withIdentifier: id) else { return }
        self.performSegue(withIdentifier: id, sender: sender)
    }
}

// 1
if canPerformSegue("test") {
    performSegueIfPossible(id: "test") // or with sender: , sender: ...)
}

// 2
performSegueIfPossible(id: "test") // or with sender: , sender: ...)
Run Code Online (Sandbox Code Playgroud)


Rui*_*res 6

如文档中所述:

应用程序通常不需要直接触发segue.而是在Interface Builder中配置与视图控制器关联的对象(例如嵌入在其视图层次结构中的控件)以触发segue.但是,您可以调用此方法以编程方式触发segue,可能是为了响应无法在storyboard资源文件中指定的某些操作.例如,您可以从用于处理抖动或加速度计事件的自定义操作处理程序中调用它.

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

话虽如此,当你触发时segue,通常是因为它假设UIViewController能够用特定的segue's标识符响应它.我也同意Dan F,你应该尽量避免抛出异常的情况.作为你不能做这样的事情的原因:

if ([self canPerformSegueWithIdentifier:@"SegueID"])
    [self performSegueWithIdentifier:@"SegueID"];
Run Code Online (Sandbox Code Playgroud)

我在猜测:

  1. respondsToSelector:仅检查您是否能够在运行时处理该消息.在这种情况下你可以,因为该类UIViewController能够响应performSegueWithIdentifier:sender:.要实际检查的方法是能够处理消息的某些参数,我想这是不可能的,因为,以确定是否有可能有实际运行它,这样做的时候NSInvalidArgumentException会上升.
  2. 要实际创建您建议的内容,接收UIViewController与之关联的segue id列表会很有帮助.从UIViewController 文档中,我无法找到任何类似的东西

至于现在,我猜你最好的选择就是坚持下去@try @catch @finally.