web-dev-qa-db-fra.com

Xcode 6 Storyboard Unwind Segue avec Swift Pas de connexion à la sortie

Lorsque vous essayez de connecter un bouton de barre de navigation à l'élément de sortie d'un ViewController dans Xcode 6 (vous ne savez pas vraiment s'il s'agit d'un problème de Xcode 6 mais vous devez le mentionner car il est en version bêta), il ne trouve pas la fonction Swift dans la classe personnalisée.

Button to Exit with whip

La fonction à rechercher:

@IBAction func unwindToList(segue: UIStoryboardSegue) {

}

J'ai créé un autre bouton dans la vue pour m'assurer que IBAction fonctionnerait avec Swift et que je l'écrivais correctement. Cela fonctionne bien:

@IBAction func test(sender: AnyObject) {

    NSLog("Test")
}

J'ai vu cette question cela semble être le même problème, mais selon les réponses fournies, cela devrait fonctionner.

Xcode 6 est en version bêta et, bien sûr, Swift est très nouveau, mais voulait savoir si quelqu'un l'avait déjà remarqué avant de le considérer comme un bug potentiel.

51
skabob11

C'est un problème connu avec Xcode 6:

Unwind segue actions déclarées dans Swift ne sont pas reconnues par Interface Builder

Pour le contourner, vous devez:

  1. Remplacez class MyViewController Par @objc(MyViewController) class MyViewController
  2. Créez un fichier d'en-tête Objective-C avec une catégorie pour MyViewController qui redéclare l'action de division.

    @interface MyViewController (Workaround)
    - (IBAction)unwindToMyViewController: (UIStoryboardSegue *)segue;
    @end
    
  3. Dans le storyboard, sélectionnez l'instance de MyViewController, effacez sa classe personnalisée, puis redéfinissez-la sur MyViewController.

Après ces étapes, vous pouvez connecter à nouveau des boutons à l'élément de sortie.

Notes de version de Xcode 6 PDF, page 10

55
skabob11

Au lieu d'utiliser la solution de contournement d'Objective-C, Xcode 6 Bêta 4, qui peut maintenant être installé, prend en charge la connexion des segments de déroulement dans le Générateur d'interface. Vous pouvez maintenant mettre à jour à partir du centre de développement iOS. Cliquez en maintenant la touche Contrôle enfoncée et en faisant glisser l'élément de l'interface utilisateur dont vous souhaitez déclencher la transition vers l'icône de sortie, puis sélectionnez la fonction unwindToSegue après avoir placé le code suivant dans le contrôleur de vue de destination.

@IBAction func unwindToSegue (segue : UIStoryboardSegue) {}
51
trumpeter201

J'ai pu enfin le faire fonctionner; Le xcode6 IB est très fragile en ce moment (il plante beaucoup aussi). Je devais redémarrer le IDE avant de pouvoir connecter le bouton de la barre de navigation à la sortie. J'ai fini par recréer mon projet de test et en suivant la suggestion ci-dessus (Notes de version Xcode 6 PDF, De plus, lors de l’ajout du fichier .h, j’ai veillé à sélectionner la cible de mon projet, qui était désélectionnée par défaut, j’ai également créé mon contrôleur Swift stub via le modèle Cocoa Touch Class (vs empty Swift). J'ai utilisé une séquence modale dans mon contrôleur de navigation.

ListTableViewController.h

#import <UIKit/UIKit.h>

@interface ListTableViewController
- (IBAction)unwindToList: (UIStoryboardSegue *)segue;
@end

ListTableViewController.Swift

import UIKit

@objc(ListTableViewController) class ListTableViewController: UITableViewController {

    @IBAction func unwindToList(s:UIStoryboardSegue) {
        println("hello world");
    }

}

j'espère que ça t'as aidé

16
rajeev

Dans Xcode 6 Beta 4, qui est disponible au téléchargement, les séquences de déroulement et le constructeur d’interface sont pris en charge. Je l'ai testé par moi-même dans un petit projet.

11
Fred

Dans Swift 2.3 j'ai trouvé le nom externe du paramètre doit être "withUnwindSegue":

@IBAction func unwindToThisView(withUnwindSegue unwindSegue: UIStoryboardSegue) {
    ...
}
5
Bob Peterson

Il semble que Xcode 6.1 ait résolu ce problème. Vous pouvez maintenant configurer les segments de déroulement dans Swift avec le code suivant:

@IBAction func unwindToList(segue: UIStoryboardSegue) {
    // Nothing needed here, maybe a log statement
    // print("\(segue)")
}

Cette méthode - qui peut rester vide - doit avoir une signature de méthode avec le type UIStoryboardSegue et non AnyObject ou Interface Builder ne la verra pas.

Pour plus de détails, consultez le TechNote 2298

2
Barlow Tucker

Si c'est toujours le même contrôleur de vue de présentation que vous souhaitez décompresser, vous pouvez toujours faire:

self.navigationController?.popViewControllerAnimated(true)
1
bkopp

J'ai eu le même problème, également avec Xcode Beta 4 au début .. jusqu'à ce que j'ai découvert, que j'ai simplement oublié d'ajouter le @IBOutlet pour les boutons Annuler et Enregistrer dans le contrôleur respectif. Après cela, je pourrais connecter les boutons avec l'icône de sortie :))

1
Andreas Meyer

Vous voudrez peut-être vérifier que la destination du contrôleur d'origine à laquelle vous essayez de vous dérouler n'est pas incorporée dans un objet Container. Xcode 6 n'est pas ça.

1
TMfranken

Les réponses ci-dessus reposent sur ObjC pour résoudre le problème. J'ai trouvé une solution pure Swift. Lors de l'ajout du gestionnaire de division dans Swift m'a permis de créer le segue dans Interface Builder (Xcode 6.3), le gestionnaire n’était pas appelé.

@IBAction func unwindToParent(sender: UIStoryboardSegue) {
    dismissViewControllerAnimated(true, completion: nil)
}

Donc, après avoir creusé, le canPerformUnwindSegueAction:fromViewController:withSender de la super classe renvoie false. J'ai donc remplacé l'implémentation et cela fonctionne:

override func canPerformUnwindSegueAction(action: Selector, fromViewController: UIViewController, withSender sender: AnyObject) -> Bool {
    return action == Selector("unwindToParent:")
}

Mettre à jour
Le code ci-dessus est incorrect, car j'ai résolu le problème sans surcharger canPerformUnwindSegueAction:fromViewController:withSender. L'erreur fondamentale était de faire la distinction entre le présenter viewcontroller et le présenté viewcontroller.

Lorsqu'une séquence de déroulement est initiée, il doit d'abord localiser le contrôleur de vue le plus proche dans la hiérarchie de navigation qui implémente l'action de déroulement spécifiée lors de la création de la séquence de déroulement. Ce contrôleur de vue devient la destination de la séquence de déroulement. Si aucun contrôleur de vue approprié n'est trouvé, la séquence de déroulement est abandonnée.
source: Note technique TN2298

Alors, définissez le @IBAction sur le contrôleur de vue présenté, pas sur le contrôleur de vue présenté. De cette manière, le segue aura des valeurs significatives pour les propriétés destinationViewController et sourceViewController également, en tant que contrôleur de vue présent et présenté.

0
Bouke

Xcode --version 6.4 Swift 1.2

@IBAction func backButton (expéditeur: AnyObject) {rejetViewControllerAnimated (true, complétion: nil)}

0
cam_271