128 votes

Comment utiliser un seul storyboard uiviewcontroller pour plusieurs sous-classes

Supposons que j'ai une storyboard qui contient UINavigationController en tant que contrôleur de vue initial. Son contrôleur de vue racine est une sous-classe de UITableViewController, qui est BasicViewController. Il a un IBAction qui est connecté au bouton de navigation droit de la barre de navigation

À partir de là, je voudrais utiliser la storyboard comme un modèle pour d'autres vues sans avoir à créer de storyboards supplémentaires. Disons que ces vues auront exactement la même interface mais avec le contrôleur de vue racine de la classe SpecificViewController1 et SpecificViewController2 qui sont des sous-classes de BasicViewController.
Ces 2 contrôleurs de vue auraient la même fonctionnalité et interface sauf pour la méthode IBAction.
Ce serait comme suit :

@interface BasicViewController : UITableViewController

@interface SpecificViewController1 : BasicViewController

@interface SpecificViewController2 : BasicViewController

Puis-je faire quelque chose comme ça?
Puis-je simplement instancier la storyboard de BasicViewController mais avoir le contrôleur de vue racine comme une sous-classe de SpecificViewController1 et SpecificViewController2?

Merci.

3 votes

Il pourrait être utile de mentionner que vous pouvez le faire avec Nib. Mais si vous êtes comme moi et que vous voulez certaines fonctionnalités intéressantes que seul le storyboard a (cellule statique/prototype, par exemple), alors je suppose que nous n'avons pas de chance.

0 votes

0 votes

Est-ce que cela répond à votre question? Jeter à une sous-classe depuis Storyboard

1voto

DanSkeel Points 1240

Probablement la façon la plus flexible est d'utiliser des vues réutilisables.

(Créez une vue dans un fichier XIB séparé ou vue de conteneur et ajoutez-la à chaque scène du contrôleur de vue de sous-classe dans le storyboard)

1voto

nickgzzjr Points 151

En prenant des réponses ici et là, j'ai trouvé cette solution astucieuse.

Créez un contrôleur de vue parent avec cette fonction.

class ParentViewController: UIViewController {

    func convert(to _: T.Type) {

        object_setClass(self, T.self)

    }

}

Cela permet au compilateur de s'assurer que le contrôleur de vue enfant hérite du contrôleur de vue parent.

Ensuite, chaque fois que vous souhaitez faire une transition vers ce contrôleur en utilisant une sous-classe, vous pouvez faire :

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    if let parentViewController = segue.destination as? ParentViewController {
        ParentViewController.convert(to: ChildViewController.self)
    }

}

La partie intéressante est que vous pouvez ajouter une référence de storyboard à elle-même, puis continuer à appeler le "prochain" contrôleur de vue enfant.

0voto

Sayka Points 435

Le commentaire de Cocoabob en réponse à Jirí Zahálka m'a aidé à obtenir cette solution et cela a bien fonctionné.

func openChildA() {
    let storyboard = UIStoryboard(name: "Main", bundle: nil);
    let parentController = storyboard
        .instantiateViewController(withIdentifier: "ParentStoryboardID") 
        as! ParentClass;
    object_setClass(parentController, ChildA.self)
    self.present(parentController, animated: true, completion: nil);
}

-1voto

Archangel Points 16

C'est simplement. Il suffit de définir le BaseViewController dans un xib et ensuite l'utiliser comme ceci:

let baseVC: BaseViewController = BaseViewController(nibName: "BaseViewController", bundle: nil)
let subclassVC: ChildViewController = ChildViewController(nibName: "BaseViewController", bundle: nil)

Pour simplifier, vous pouvez extraire l'identifiant dans un champ et le chargement dans une méthode comme ceci:

public static var baseNibIdentifier: String {
    return "BaseViewController"
}

public static func loadFromBaseNib() -> T where T : UIViewController {
    return T(nibName: self.baseNibIdentifier, bundle: nil)
}

Ensuite, vous pouvez l'utiliser comme ceci:

let baseVC: BaseViewController = BaseViewController.loadFromBaseNib()
let subclassVC: ChildViewController = ChildViewController.loadFromBaseNib()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X