这可能是一个非常简单的问题,但当我搜索时没有得到任何结果,所以在这里提出来...
我想找到一种方法,在调用performSegueWithIdentifier:
方法之前检查某个视图控制器是否能够使用标识符XYZ执行segue。
类似于以下内容:
if ([self canPerformSegueWithIdentifier:@"SegueID"])
[self performSegueWithIdentifier:@"SegueID"];
可能吗?
这可能是一个非常简单的问题,但当我搜索时没有得到任何结果,所以在这里提出来...
我想找到一种方法,在调用performSegueWithIdentifier:
方法之前检查某个视图控制器是否能够使用标识符XYZ执行segue。
类似于以下内容:
if ([self canPerformSegueWithIdentifier:@"SegueID"])
[self performSegueWithIdentifier:@"SegueID"];
可能吗?
为了检查是否存在segue,我只是用try-and-catch块包围了调用。请参见下面的代码示例:
@try {
[self performSegueWithIdentifier:[dictionary valueForKey:@"segue"] sender:self];
}
@catch (NSException *exception) {
NSLog(@"Segue not found: %@", exception);
}
希望这可以帮助你。
Hope this helps.
返回结果:希望这可以帮助你。
performSegueWithIdentifier:sender:
消息以及所有子视图控制器(因为UIKit保留视图控制器但从未有机会释放它,由于异常)。 - Guillaume Algis- (BOOL)canPerformSegueWithIdentifier:(NSString *)identifier
{
NSArray *segueTemplates = [self valueForKey:@"storyboardSegueTemplates"];
NSArray *filteredArray = [segueTemplates filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"identifier = %@", identifier]];
return filteredArray.count>0;
}
这篇文章已更新至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: ...)
根据文档所述:
应用程序通常不需要直接触发segue。 相反,您可以在与视图控制器相关联的Interface Builder中配置一个对象, 例如嵌入在其视图层次结构中的控件,以触发segue。但是,您可以调用此方法来以编程方式触发segue, 也许作为对无法在故事板资源文件中指定的某些操作的响应。例如,您可能会从自定义操作处理程序中调用它, 该处理程序用于处理摇晃或加速度计事件。
接收此消息的视图控制器必须已从故事板加载。 如果视图控制器没有关联的故事板,可能是因为您自己分配和初始化了它, 则此方法会引发异常。
话虽如此,当您触发segue
时,通常是因为假定UIViewController
将能够使用特定的segue
标识符进行响应。我也同意Dan F的看法,您应该尝试避免可能会引发异常的情况。
这是您无法执行此类操作的原因:
if ([self canPerformSegueWithIdentifier:@"SegueID"])
[self performSegueWithIdentifier:@"SegueID"];
respondsToSelector:
只检查是否能够在运行时处理该消息。在这种情况下,您可以,因为类UIViewController
能够响应performSegueWithIdentifier:sender:
。要实际检查方法是否能够处理带有某些参数的消息,我想这是不可能的,因为为了确定是否可能,它必须实际运行它,并且在这样做时会引发NSInvalidArgumentException
。UIViewController
相关联的segue id列表。从UIViewController
的文档中,我无法找到任何看起来像那样的内容。@try
@catch
@finally
。- (BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
if ([identifier isEqualToString:@"someSegue"]) {
if (!canIPerformSegue) {
return NO;
}
}
return YES;
}
import UIKit
extension UIViewController{
func canPerformSegue(identifier: String) -> Bool {
guard let identifiers = value(forKey: "storyboardSegueTemplates") as? [NSObject] else {
return false
}
let canPerform = identifiers.contains { (object) -> Bool in
if let id = object.value(forKey: "_identifier") as? String {
return id == identifier
}else{
return false
}
}
return canPerform
}
}
在调用 performSegue 之前,检查基础 UIViewController 上的本地 storyboard 属性将会很有用(例如屏幕是来自 StoryBoard 还是手动实例)
extension UIViewController {
func performSegueWithValidate(withIdentifier identifier: String, sender: Any?) {
if storyboard != nil {
performSegue(withIdentifier: identifier, sender: sender)
}
}
在此输入图片描述
以下是 Evgeny Mikhaylov 的答案的 Swift 版本,对我很有用:
我在两个视图中重复使用一个控制器。这帮助我重复使用代码。
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)
}
canRunSegueWithIdentifier
。 - Andrey Gordeev使用标准函数无法检查,您可以做的是子类化UIStoryboardSegue
并将信息存储在传递给构造函数的source
视图控制器中。在界面生成器中选择“自定义”作为segue类型,然后输入segue的类名,这样每个实例化的segue都会调用您的构造函数,如果存在存储的数据,则可以查询它。
您还必须重写perform
方法,以调用[source presentModalViewController:destination animated:YES]
或[source pushViewController:destination animated:YES]
,具体取决于您想要的过渡类型。
@try @catch @finally
。它运行良好。 - RogUITableViewCell
实例,并希望配置它们的附件)。有很多其他方法可以实现相同的目标(我正在使用其中一种),但我能想到的方法会导致重复,而我想避免这种情况。 - Benjohn