uiview autolayout interface-builder uistoryboard xib

Reutilice un uiview xib en el guión gráfico



autolayout interface-builder (7)

Normalmente me gusta crear y diseñar mis uiviews en el generador de interfaces. A veces necesito crear una vista única en un xib que pueda reutilizarse en múltiples controladores de vista en un guión gráfico.


Actualización rápida 3 y 4 a la respuesta aceptada

1. Cree una nueva UIView llamada ''DesignableXibView''

  • Archivo> Nuevo> Archivo> Origen> Cocoa Touch Class> UIView

2. Cree un archivo xib coincidente llamado ''DesignableXibView''

  • Archivo> Nuevo> Archivo> Interfaz de usuario> Ver

3. Establezca el propietario del archivo de xib

Seleccione "DesignableXibView.xib"> "Propietario del archivo"> ​​establezca "Clase personalizada" en ''DesignableXibView'' en el Inspector de identidad.

  • Nota: No establezca la clase personalizada de la vista en el xib. ¡Solo el propietario del archivo!

4. Implementación de DesignableXibView

import UIKit @IBDesignable class DesignableXibView: UIView { var contentView : UIView! override init(frame: CGRect) { super.init(frame: frame) xibSetup() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) xibSetup() } func xibSetup() { contentView = loadViewFromNib() // use bounds not frame or it''ll be offset contentView.frame = bounds // Make the view stretch with containing view contentView.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight] // Adding custom subview on top of our view addSubview(contentView) } func loadViewFromNib() -> UIView! { let bundle = Bundle(for: type(of: self)) let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle) let view = nib.instantiate(withOwner: self, options: nil).first as! UIView return view } }

5 Pruebe su vista reutilizable en un guión gráfico

  • Abre tu storyboard

  • Agregar una vista

  • Establecer la clase personalizada de esa vista


Para cualquiera que intente adaptar la respuesta aceptada (por @Garfbargle) a Objective-C

Simplemente convertir Swift a Objective-C no es suficiente para que funcione. He tenido dificultades para permitir la representación en vivo en Storyboard.

Después de traducir todo el código, la vista se carga bien cuando se ejecuta en el dispositivo (o simulador), pero la representación en vivo en Storyboard no funciona. La razón de esto es que usé [NSBundle mainBundle] mientras que Interface Builder no tiene acceso a mainBundle. Lo que debe usar en su lugar es [NSBundle bundleForClass:self.classForCoder] . BOOM, ¡la representación en vivo funciona ahora!

Nota: si tiene problemas con el diseño automático, intente deshabilitar las Safe Area Layout Guides en Xib.

Para su conveniencia, dejo todo mi código aquí, para que solo tenga que copiar / pegar (para todo el proceso, siga la respuesta original ):

BottomBarView.h

#import <UIKit/UIKit.h> IB_DESIGNABLE @interface BottomBarView : UIView @end

BottomBarView.m

#import "BottomBarView.h" @interface BottomBarView() { UIView *contentView; } @end @implementation BottomBarView -(id) initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self xibSetup]; } return self; } -(id) initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self xibSetup]; } return self; } -(void) xibSetup { contentView = [self loadViewFromNib]; contentView.frame = self.bounds; contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self addSubview:contentView]; } -(UIView*) loadViewFromNib { NSBundle *bundle = [NSBundle bundleForClass:self.classForCoder]; //this is the important line for view to render in IB UINib *nib = [UINib nibWithNibName:NSStringFromClass([self class]) bundle:bundle]; UIView *view = [nib instantiateWithOwner:self options:nil][0]; return view; } @end

Dígame si encuentra algunos problemas, pero casi debería salir de la caja :)


Reutilice y renderice un xib en un guión gráfico.

Probado con Swift 2.2 y Xcode 7.3.1

1 ---- Cree una nueva UIView llamada ''DesignableXibView''

  • Archivo> Nuevo> Archivo> Origen> Cocoa Touch Class> UIView

2 ---- Cree un archivo xib coincidente llamado ''DesignableXibView''

  • Archivo> Nuevo> Archivo> Interfaz de usuario> Ver

3 ---- Establecer el propietario del archivo de la xib

  1. seleccione el xib
  2. seleccione el propietario del archivo
  3. establezca la clase personalizada en ''DesignableXibView'' en el Inspector de identidad.

  • Nota: No establezca la clase personalizada de la vista en el xib. ¡Solo el propietario del archivo!

4 ---- Implementación de DesignableXibView

// DesignableXibView.swift import UIKit @IBDesignable class DesignableXibView: UIView { var contentView : UIView? override init(frame: CGRect) { super.init(frame: frame) xibSetup() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) xibSetup() } func xibSetup() { contentView = loadViewFromNib() // use bounds not frame or it''ll be offset contentView!.frame = bounds // Make the view stretch with containing view contentView!.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight] // Adding custom subview on top of our view (over any custom drawing > see note below) addSubview(contentView!) } func loadViewFromNib() -> UIView! { let bundle = NSBundle(forClass: self.dynamicType) let nib = UINib(nibName: String(self.dynamicType), bundle: bundle) let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView return view } }

5 ---- Pon a prueba tu vista reutilizable en un guión gráfico

  1. Abre tu storyboard
  2. Agregar una vista
  3. Establecer la clase personalizada de esa vista
  4. espera un segundo ... BOOM !!


Aquí está la respuesta que siempre has querido. Puede crear su clase CustomView , tener la instancia maestra de la misma en un xib con todas las subvistas y salidas. Luego, puede aplicar esa clase a cualquier instancia en sus guiones gráficos u otras xibs.

No es necesario jugar con el propietario del archivo, o conectar salidas a un proxy o modificar el xib de una manera peculiar, o agregar una instancia de su vista personalizada como una subvista de sí mismo.

Solo haz esto:

  1. Importar marco de BFWControls
  2. Cambie su superclase de UIView a NibView (o de UITableViewCell a NibTableViewCell )

¡Eso es!

Incluso funciona con IBDesignable para representar su vista personalizada (incluidas las subvistas del xib) en tiempo de diseño en el guión gráfico.

Puede leer más sobre esto aquí: https://medium.com/build-an-app-like-lego/embed-a-xib-in-a-storyboard-953edf274155

Y puede obtener el marco de código abierto de BFWControls aquí: https://github.com/BareFeetWare/BFWControls

Tom 👣


La función initWithCoder en swift 2 si alguien tiene problemas para traducirlo:

required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) UINib(nibName: String(self.dynamicType), bundle: NSBundle.mainBundle()).instantiateWithOwner(self, options: nil) self.addSubview(view) self.view.translatesAutoresizingMaskIntoConstraints = false self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[view]|", options: NSLayoutFormatOptions.AlignAllCenterY , metrics: nil, views: ["view": self.view])) self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: NSLayoutFormatOptions.AlignAllCenterX , metrics: nil, views: ["view": self.view])) }


Si alguien está interesado, aquí está la versión Xamarin.iOS del código Paso 4 de @Garfbargle

public partial class CustomView : UIView { public ErrorView(IntPtr handle) : base(handle) { } [Export("awakeFromNib")] public override void AwakeFromNib() { var nibObjects = NSBundle.MainBundle.LoadNib("CustomView", this, null); var view = (UIView)Runtime.GetNSObject(nibObjects.ValueAt(0)); view.Frame = Bounds; view.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight; AddSubview(rootView); } }


¡NUEVO! respuesta actualizada con capacidad de renderizar directamente en el guión gráfico (¡y rápido!)

Funciona en Xcode 6.3.1

Cree una nueva UIView llamada ''ReuseableView''

  • Archivo> Nuevo> Archivo> Origen> Cocoa Touch Class> UIView

Cree un archivo xib coincidente llamado ''ReuseableView''

  • Archivo> Nuevo> Archivo> Interfaz de usuario> Ver

Establecer el propietario del archivo de xib

  1. seleccione el xib
  2. seleccione el propietario del archivo
  3. establezca la clase personalizada en ''ReusableView'' en el Inspector de identidad.

    • Nota: No establezca la clase personalizada de la vista en el xib. ¡Solo el propietario del archivo!

Haga una salida desde la vista en ReuseableView.xib a su interfaz ReuseableView.h

  1. Editor asistente abierto
  2. Control + Arrastrar desde la vista a su interfaz

Agregue la implementación initWithCoder para cargar la vista y agregue como una subvista.

- (id)initWithCoder:(NSCoder *)aDecoder{ self = [super initWithCoder:aDecoder]; if (self) { // 1. load the interface [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil]; // 2. add as subview [self addSubview:self.view]; // 3. allow for autolayout self.view.translatesAutoresizingMaskIntoConstraints = NO; // 4. add constraints to span entire view [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:@{@"view":self.view}]]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|" options:0 metrics:nil views:@{@"view":self.view}]]; } return self; }

Pon a prueba tu vista reutilizable en un guión gráfico

  1. Abre tu storyboard
  2. Agregar una vista
  3. Establecer la clase personalizada de esa vista

¡Corre y observa!