2010-10-15 4 views
25

Je crée un widget personnalisé que j'aimerais utiliser dans plusieurs plumes. Donc, je fais une nouvelle vue nib Screen3, ajouter des boutons, et maintenant je veux mon widget UIAwesomeSauce.Comment puis-je obtenir une vue dans Interface Builder pour charger une vue personnalisée dans une autre plume?

Si je viens d'ajouter une vue, puis de changer l'identité de la classe, elle n'obtient pas les sous-éléments de la plume UIAwesomeSauce. Même chose si je vais à la bibliothèque et passer aux classes. Il semble que seul un UIViewController a le champ pour "Load from nib", ce qui serait beau. Je sais que je peux charger la plume UIAwesomeSauce à partir du code, obtenir les objets de niveau supérieur, et le placer à la main. Mais le but de IB est de ne pas avoir à placer les choses dans le code. Mieux encore, je pourrais faire apparaître UIAwesomeSauce dans la liste des bibliothèques.

RESOLU - par Nimrod - LIRE SUR LE CODE ET EXPLICATION POUR

Quoi qu'il en soit, dood, ce qui est grand. Je peux faire mes propres classes de widget maintenant pour des trucs géniaux. Faites en sorte que FileOwner de votre interface utilisateur soit votre classe, et qu'elle ait juste un UIView normal avec toutes vos affaires. (La seule vue dans la plume du widget ne peut pas être la classe elle-même, ou vous obtenez récursif dans initWithCoder.) Ensuite, dans la plume que vous voulez utiliser, faites un UIView vanille et changez sa classe. Vous ne pourrez pas réellement voir le widget à l'intérieur de ce carré, mais traitez. Self est maintenant une vue vide, et tMyActualSelf est la vue unique dans laquelle vous avez travaillé dans l'autre nib. Yay!

- (id)initWithCoder:(NSCoder*)coder 
{ 
    if ((self = [super initWithCoder:coder])) 
    { 
     UIView *tMyActualSelf = nil; 
     // Initialization code 
     NSArray *tNibItems = [[NSBundle mainBundle] loadNibNamed:@"UIAwesomeSauce" owner:self options:nil]; 
     for (id object in tNibItems) 
     { 
      if ([object isKindOfClass:[UIView class]]) 
       tMyActualSelf = (UIView *)[object retain]; 
     } 
     if(tMyActualSelf) 
     { 
      tMyActualSelf.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 
      [self addSubview:tMyActualSelf]; 
     } 
    } 
    return self; 
} 

Répondre

14

Je ressens votre douleur quand il vient à la UIViewController être la seule chose que vous pouvez spécifier une charge de pointe avec, mais je pense qu'il est parce qu'il doit être propriétaire qui est un contrôleur d'un fichier, ou quelque chose comme ça, Je ne sais pas pourquoi un UIView ne peut pas être le propriétaire d'un fichier.

Je pense que vous pouvez mettre des éléments dans la bibliothèque sous Objets personnalisés, mais je pense que vous seriez limité à mettre un UIView là avec la classe juste définie à une sous-classe personnalisée de UIView. J'ai effectivement cherché à étendre le constructeur d'interface et il semble que vous puissiez le faire pour OS X, mais pas pour iPhone. Cela implique de compiler du code pour le nouveau widget dans le constructeur d'interface pour lui indiquer comment dessiner le widget juste dans IB. Je pense qu'il existe un modèle OS X pour cela.

Je pense que je ferais probablement une vue principale dans un fichier nib contenant toutes les sous-vues, puis dans initWithCoder: dans la chose UIAwesomeSauce, ouvrez le fichier nib, chargez la vue principale et placez-la moi-même afin que vous ayez une vue "inutile" entre la vue UIAwesomeSauce et les sous-vues (ou les sous-vues selon le cas.) Je ne suis pas sûr de l'inefficacité, mais en jouant avec certaines choses, ça ressemble à des vues UIWebView semble avoir un de ces points de vue intermédiaires apparemment inutiles (IIRC).

Si vous trouvez une meilleure solution, dites-le moi parce que j'aimerais aussi le savoir.

EDIT

Maintenant que je regarde, je pense que le UIView PEUT être le propriétaire du fichier, vous ne pouvez pas le mettre dans IB. Fondamentalement, vous appelez quelque chose de charge de pointe comme celui-ci dans la sous-classe UIView:

[paquet loadNibNamed: @ « UISpecialSauce » propriétaire: auto Options: ...]

Je pense que si vous créez ou points de vente dans UISpecialSauce quoi qu'il en soit, ils devraient être attribués correctement à cause du propriétaire: soi-même.

+1

C'est tellement brillant que je veux vous faire une tarte. – CBGraham

+0

Yay! J'ai finalement eu assez de points pour voter sur les billets, alors voilà. (Vous devriez être en mesure de voter sur des messages sur vos propres questions, tout comme vous pouvez commenter les messages sur vos propres questions.) – CBGraham

+0

Pour quelqu'un (comme moi) qui a scanné la question et lire la réponse en détail, le demandeur a mis son "RESOLU "code comme un edit dans sa question originale. –

1

Theres un cocoapod qui pourrait effectivement aider à cela: https://github.com/mobilejazz/NibWrapper

Il fournit une vue wrapper qui charge une vue de l'enfant d'un autre NIB. Vous pouvez spécifier le nom de cette NIB dans le générateur d'interface via un attribut d'exécution.

+0

Merci, j'ai utilisé ceci après avoir trouvé votre référence. Était une aide précieuse après des jours de lecture. Seul honte est qu'il existe un niveau d'indirection car vous devez définir un espace réservé UIView (de la classe UINibWraper), et à partir de là vous pouvez obtenir une référence à votre UIView personnalisé. Il y a un autre cocoapod qui adopte une approche différente qui, en théorie, supprime ce calque supplémentaire (UIView + NibLoading), mais l'utilisation de contraintes de mise en forme automatique dans la vue personnalisée l'a écrasé pour moi. –

Questions connexes