Swift: asigna una NIB a uno mismo en la class

Estoy creando una subclass UIView para un banner desplegable de notifications. Estoy usando un XIB para build la vista y quiero asignar ese xib a la class cuando se inicializa (es decir, evitando tener que hacer esto desde el ViewController que llama).

Dado que no puede asignarse a 'self' de manera rápida, ¿cómo hago esto correctamente dentro de la class misma?

class MyDropDown: UIView { func showNotification() { self = UINib(nibName: nibNamed, bundle: bundle).instantiateWithOwner(nil, options: nil)[0] as? UIView } } 

Para cualquiera que busque cómo inicializar un xib de su propia class en forma rápida, este es el mejor enfoque para usar un inicializador de class personalizado:

 class MyCustomView: UIView { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var titleLabel: UILabel! class func initWithTitle(title: String, image: UIImage? = nil) -> MyCustomView { var myCustomView = UINib(nibName: "MyCustomView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as? MyCustomView myCustomView.titleLabel.text = title if image != nil { myCustomView.imageView.image = image } //...do other customization here... return myCustomView } } 

Mi enfoque habitual es el siguiente:

  1. Establezca mi class de vista personalizada como FileOwner en la punta
  2. Establecer todas las tomas y acciones requeridas.
  3. Establezca la salida a la vista en la punta y nómbrelos 'contentView' en la class
  4. En el método init* , inicie la plumilla con el propietario y agregue la subvista a mi object de vista personalizada.

Aquí está el ejemplo de la vista del encabezado de colección implementada de esta manera.

 @interface Header : UITableViewHeaderFooterView @property (nonatomic) IBOutlet UIView *contentView; @property (weak, nonatomic) IBOutlet UILabel *labelTitle; // other requinetworking outlets & actions // ... @end #import "Header.h" @implementation Header - (id)initWithReuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithReuseIdentifier:reuseIdentifier]) { [[NSBundle mainBundle] loadNibNamed:@"Header" owner:self options:nil]; [self.contentView addSubview:self.content]; UIView *subview = self.content; self.content.translatesAutoresizingMaskIntoConstraints = NO; NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(subview); [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview]|" options:0 metrics: 0 views:viewsDictionary]]; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview]|" options:0 metrics: 0 views:viewsDictionary]]; } return self; } @end 

// ACTUALIZAR Ejemplo rápido

La idea principal no es cargar vista desde la punta directamente a self sino agregarla / verla desde la punta / como una subvista al self

 import UIKit class CustomView: UIView { @IBOutlet var contentView: UIView! @IBOutlet weak var labelTitle: UILabel! requinetworking init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.__loadContent() } override init(frame: CGRect) { super.init(frame: frame) self.__loadContent() } private func __loadContent() { // create nib let nib = UINib(nibName: "CustomView", bundle: NSBundle.mainBundle()) // load outlets to self nib.instantiateWithOwner(self, options: nil) // add content view as a subview self.addSubview(self.contentView) // disable autoresizing self.contentView.setTranslatesAutoresizingMaskIntoConstraints(false) // manually create constraints to fix content view inside self with 0 padding let viewsDict: NSDictionary = ["content": self.contentView] let vertical = NSLayoutConstraint.constraintsWithVisualFormat("V:|[content]|", options: NSLayoutFormatOptions.allZeros, metrics: nil, views: viewsDict) let horizontal = NSLayoutConstraint.constraintsWithVisualFormat("H:|[content]|", options: NSLayoutFormatOptions.allZeros, metrics: nil, views: viewsDict) self.addConstraints(vertical) self.addConstraints(horizontal) } } 

InterfaceBuilder