Utiliser une class générique en tant que vue personnalisée dans Interface Builder

J'ai une sous-class personnalisée de UIButton:

import UIKit @IBDesignable class MyButton: UIButton { var array : [Ssortingng]? } 

C'est IBDesignable et je l'ai défini en tant que class personnalisée pour l'un des buttons de mon storyboard. Je voudrais le rendre générique afin que le tableau ne doive pas être un des objects Ssortingng. Donc, j'ai essayé ceci:

 import UIKit @IBDesignable class MyButton<T>: UIButton { var array : [T]? } 

Cependant, je ne sais pas comment définir ceci comme class maintenant dans IB. J'ai essayé de mettre MyButton<Ssortingng> ou MyButton<Int> , mais Interface Builder supprime simplement la partie des crochets et obtient l'erreur de compilation suivante:

 Command /Applications/Xcode6-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254 

Existe-t-il un moyen d'utiliser une class personnalisée générique ou n'est-il pas pris en charge?

    Interface Builder "parle" à votre code via l'environnement d'exécution ObjC. En tant que tel, IB ne peut accéder qu'aux fonctionnalités de votre code qui sont représentables dans le runtime ObjC. ObjC ne fait pas de generics, donc IB n'a aucun moyen de dire à l'exécution quelle spécialisation de votre class générique utiliser. (Et une class générique Swift ne peut pas être instanciée sans une spécialisation, donc vous obtenez une erreur essayant d'instancier un MyButton au lieu d'un MyButton<WhateverConcreteType> .)

    (Vous pouvez reconnaître le runtime ObjC à l'œuvre dans IB lorsque vous détruisez d'autres choses: Tenter d'utiliser une class Swift pure avec des points / actions dans une plume / storyboard donne des erreurs d'exécution sur l'introspection ObjC. ou disparu donne des erreurs d'exécution au sujet de KVC.

    Pour ignorer les problèmes d'exécution et le mettre d'une manière légèrement différente … revenons à ce que l'IB a besoin de savoir. Rappelez-vous que le système de chargement de la plume est ce qui instancie quoi que ce soit dans un storyboard au moment de l'exécution. Donc, même si les parties de votre class qui prennent un paramètre de type générique ne sont pas @IBInspectable , la @IBInspectable doit toujours savoir quelle spécialisation de votre class générique charger. Donc, pour que IB vous laisse utiliser des classs generics pour les vues, IB devrait avoir une place pour vous permettre d'identifier la spécialisation de votre class que la plume devrait utiliser. Ce n'est pas le cas – mais cela ferait une excellente request de fonctionnalités .

    En attendant, s'il est toujours utile pour votre class MyButton d'impliquer un stockage générique, vous pourriez peut-être requestr à MyButton reference à une autre class qui inclut le stockage générique. (Cela devrait être fait de telle sorte que le type de stockage ne soit pas connu au moment de la compilation, sinon les parameters de type de cette autre class devraient être renvoyés à MyButton .)

    J'ai eu le même problème que d'abord je voulais utiliser la structure suivante:

     import UIKit protocol MyDataObjectProtocol{ var name:Ssortingng { get} } class MyObjectTypeOne:MyDataObjectProtocol{ var name:Ssortingng { get { return "object1"}} } class MyObjectTypeTwo:MyDataObjectProtocol{ var name:Ssortingng { get { return "object2"}} } class SpecializedTableViewControllerOne: GenericTableViewController<MyObjectTypeOne> { } class SpecializedTableViewControllerTwo: GenericTableViewController<MyObjectTypeTwo> { } class GenericTableViewController<T where T:MyDataObjectProtocol>: UITableViewController { // some common code I don't want to be duplicated in // SpecializedTableViewControllerOne and SpecializedTableViewControllerTwo // and that uses object of type MyDataObjectProtocol. } 

    Mais comme expliqué dans la réponse précédente, ce n'est pas possible. J'ai donc réussi à le contourner avec le code suivant:

     import UIKit protocol MyDataObjectProtocol{ var name:Ssortingng { get} } class MyObjectTypeOne:MyDataObjectProtocol{ var name:Ssortingng { get { return "object1"}} } class MyObjectTypeTwo:MyDataObjectProtocol{ var name:Ssortingng { get { return "object2"}} } class SpecializedTableViewControllerOne: GenericTableViewController { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) super.object = MyObjectTypeOne() } } class SpecializedTableViewControllerTwo: GenericTableViewController { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) super.object = MyObjectTypeTwo() } } class GenericTableViewController : UIViewController { var object : MyDataObjectProtocol? @IBOutlet weak var label: UILabel! override func viewDidLoad() { label.text = object?.name } // some common code I don't want to be duplicated in // SpecializedTableViewControllerOne and SpecializedTableViewControllerTwo // and that uses object of type MyDataObjectProtocol. } 

    Maintenant, ma sortie d'label affiche "object1" quand je lier le SpecializedTableViewControllerOne tant que class personnalisée de mon controller de vue dans le storyboard et "object2" si je lie à SpecializedTableViewControllerTwo