C’est peut-être une question très simple mais qui n’a donné aucun résultat lors de la recherche, alors la voici ...
J'essaie de trouver un moyen de vérifier si un certain contrôleur de vue peut effectuer une transition avec l'identificateur XYZ avant d'appeler la méthode performSegueWithIdentifier:
.
Quelque chose dans le genre de:
if ([self canPerformSegueWithIdentifier:@"SegueID"])
[self performSegueWithIdentifier:@"SegueID"];
Possible?
Comme indiqué dans la documentation:
Normalement, les applications n'ont pas besoin de déclencher directement des étapes. Vous configurez plutôt un objet dans Interface Builder associé à Le contrôleur de vue, tel qu'un contrôle intégré à sa hiérarchie de vues, . pour déclencher la transition. Cependant, vous pouvez appeler cette méthode pour déclencher une séquence Par programmation, peut-être en réponse à une action qui ne peut pas spécifier Dans le fichier de ressources du storyboard. Par exemple, vous pouvez L'appeler à partir d'un gestionnaire d'actions personnalisé utilisé pour traiter les événements tremblement ou D'accéléromètre.
Le contrôleur de vue qui reçoit ce message doit avoir été chargé À partir d'un storyboard. Si le contrôleur de vue n'a pas de storyboard Associé, peut-être parce que vous l'avez alloué et initialisé vous-même, Cette méthode lève une exception.
Cela dit, lorsque vous déclenchez la segue
, c'est normalement parce qu'il est supposé que la UIViewController
pourra y répondre avec un identifiant segue's
spécifique. Je suis également d’accord avec Dan F, vous devriez essayer d’éviter les situations où une exception pourrait être levée. La raison pour laquelle vous ne pouvez pas faire quelque chose comme ceci:
if ([self canPerformSegueWithIdentifier:@"SegueID"])
[self performSegueWithIdentifier:@"SegueID"];
Je devine que:
respondsToSelector:
vérifie uniquement si vous êtes capable de gérer ce message au moment de l'exécution. Dans ce cas, vous le pouvez, car la classe UIViewController
est capable de répondre à performSegueWithIdentifier:sender:
. Pour vérifier si une méthode est capable de gérer un message avec certains paramètres, j'imagine que ce serait impossible, car pour déterminer s'il est possible de le faire, il est nécessaire de l'exécuter et la variable NSInvalidArgumentException
augmentera.UIViewController
est associée. De la UIViewController
documentation , je n’ai pas trouvé quoi que ce soit qui ressemble à çaPour le moment, votre meilleur pari est de continuer avec le @try
@catch
@finally
.
Pour vérifier si la séquence existait ou non, j'ai simplement entouré l'appel avec un bloc try-and-catch. Veuillez voir l'exemple de code ci-dessous:
@try {
[self performSegueWithIdentifier:[dictionary valueForKey:@"segue"] sender:self];
}
@catch (NSException *exception) {
NSLog(@"Segue not found: %@", exception);
}
J'espère que cela t'aides.
- (BOOL)canPerformSegueWithIdentifier:(NSString *)identifier
{
NSArray *segueTemplates = [self valueForKey:@"storyboardSegueTemplates"];
NSArray *filteredArray = [segueTemplates filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"identifier = %@", identifier]];
return filteredArray.count>0;
}
Cet article a été mis à jour pour Swift 4.
Voici un moyen plus correct rapide pour vérifier si une transition existe:
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: ...)
Vous pouvez remplacer la méthode - (BOOL) shouldPerformSegueWithIdentifier: sender: et y faire votre logique.
- (BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
if ([identifier isEqualToString:@"someSegue"]) {
if (!canIPerformSegue) {
return NO;
}
}
return YES;
}
J'espère que cela t'aides.
Version rapide de la réponse d'Evgeny Mikhaylov, qui a fonctionné pour moi:
Je réutilise un contrôleur pour deux vues. Cela m'aide à réutiliser du code.
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)
}
Référence CanPerformSegue.Swift
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
}
}