Normalmente les gusta crear y diseñar mi uiviews en el interface builder. A veces necesito para crear una sola vista en un xib que pueden ser reutilizados en múltiples vista de los controladores en un storyboard.

InformationsquelleAutor Garfbargle | 2015-05-19

7 Comentarios

  1. 124

    Reutilización y procesamiento de un xib en un storyboard.

    Probado con Swift 2.2 & Xcode 7.3.1

    1 —- Crear un nuevo UIView llamado ‘DesignableXibView’

    • Archivo > Nuevo > Archivo > Fuente > Cocoa Touch Clase > UIView

    2 —- Crear una coincidencia xib archivo llamado ‘DesignableXibView’

    • Archivo > Nuevo > Archivo > Interfaz de Usuario > Ver

    3 —- Configurar el archivo de propietario de la de la xib

    1. seleccione el xib
    2. seleccione archivo del propietario
    3. conjunto de clases personalizadas a ‘DesignableXibView’ en la Identidad del Inspector.

    La reutilización de un uiview xib en el storyboard

    • Nota: no configure la clase personalizada de la vista en el xib. Sólo el Propietario del Archivo!

    4 —- DesignableXibView Implementación del

    // 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 —- Prueba de su reutilizables ver en un storyboard

    1. Abrir su guión
    2. Agregar una vista
    3. Conjunto que ver la Clase Personalizada
    4. espera un segundo … BOOM!!

    La reutilización de un uiview xib en el storyboard

    • Gracias! Es posible que desee agregar un ejemplo del uso de las restricciones con Swift, como lo hizo en su Obj-C respuesta (con y sin VFL).
    • Hey @EvanR! Por desgracia, me encontré con algunos problemas con el intento de utilizar el diseño automático limitaciones que yo no era capaz de averiguar cómo superar. Parece que Xcode no era capaz de hacer la viva representación correctamente.
    • Yo era capaz de hacerlo funcionar con las restricciones, aunque no prueba con vivir de representación. He añadido CenterX, CenterY, Width, y Height limitaciones y funcionó bien. Me puede enviar por correo electrónico el código de ejemplo o publicar una respuesta aquí.
    • En mi xib, tengo algunas tomas y como a un par de puntos de vista y los botones. El código de falla en xibSetup() en la línea de contentView = loadFromNib(), se produce un error debido a que «esta clase no es el valor de la clave de codificación compatible con la tecla <cualquier>». Traté de hacer contentView mi punto de vista de clase, pero que aún no funciona.
    • Me respondió a mi propia pregunta, parece que la instalación de los puntos de venta ANTES de leer estos artículos diciendo que establezca el Propietario del Archivo, no la vista. Trabajó después he desconectado todos los puntos de venta, aseguró el propietario del archivo, fue correcta y, a continuación, volver a agregar todos los puntos de venta.
    • cómo podemos agregar el por que por th controles de interfaz de usuario de los clientes de la vista a cambiar la conducta del /la adición de destino desde el punto de Vista controlador
    • Gracias por esto! Muy práctico. Alguna idea de por qué la costumbre de vista no aparece en la Interfaz de vista previa?
    • ¿cuál es la razón para agregar archivo de clase para el propietario del archivo, no en el uiview ?
    • Cómo inicializar este punto de vista mediante programación en un ViewController?
    • ¿Cuál es la diferencia entre el archivo de configuración de titular vs clase personalizada?
    • Desearía que alguien me explique por qué tiene que ser el propietario del archivo en lugar de la vista
    • Asegúrese de que usted tiene @IBDesignable justo antes de la declaración de la clase, por ejemplo,@IBDesignable class DesignableXibView { ....
    • ¿Cómo le link @IBAction compartido UIView? desde Xib me refiero
    • No veo la vista previa en el interface builder, tampoco. Xcode 9
    • El código funciona cuando se ejecuta, pero en mi Xcode 9 muestra «con diseños build failed» bajo el módulo de línea
    • Si el XIB contiene cualquier UICollectionView no es la representación en el guión gráfico. Alguna idea?
    • Para cualquier persona tratando de adaptar esta respuesta para Objective-C. me enfrentaba a problemas con el live de representación al convertir a Objective-C, pero finalmente lo logró. Ver mi respuesta debajo de stackoverflow.com/a/55242994/4894980

  2. 73

    ¡NUEVO! respuesta actualizada con capacidad para procesar directamente en el guión gráfico (y swift!)

    Obras en Xcode 6.3.1

    Crear un nuevo UIView llamado ‘ReuseableView’

    • Archivo > Nuevo > Archivo > Fuente > Cocoa Touch Clase > UIView

    Crear una coincidencia xib archivo llamado ‘ReuseableView’

    • Archivo > Nuevo > Archivo > Interfaz de Usuario > Ver

    Configurar el archivo de propietario de la de la xib

    1. seleccione el xib
    2. seleccione archivo del propietario
    3. conjunto de clases personalizadas a ‘ReusableView’ en la Identidad del Inspector.
      La reutilización de un uiview xib en el storyboard

      • Nota: no configure la clase personalizada de la vista en el xib. Sólo el Propietario del Archivo!

    Hacer una toma de corriente de la vista en el ReuseableView.xib a su ReuseableView.h interfaz de

    1. Abrir El Asistente De Editor
    2. Control + Arrastrar desde el punto de vista de su interfaz

    La reutilización de un uiview xib en el storyboard

    Agregar initWithCoder implementación de vista de carga y añadir 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;
    }
    

    La reutilización de un uiview xib en el storyboard

    Prueba de su reutilizables ver en un storyboard

    1. Abrir su guión
    2. Agregar una vista
    3. Conjunto que ver la Clase Personalizada

    La reutilización de un uiview xib en el storyboard

    Ejecutar y observar!
    La reutilización de un uiview xib en el storyboard

    • Agregar en la parte superior de esto… es posible mostrar en el guión de los subelementos de la xib? En el último paso, el agregado de la vista aparece como un cuadrado gris, es de alguna manera de arreglarlo? Thx!
    • Sí, sin embargo, usted tiene que tomar un enfoque completamente diferente. Tienes que crear mediante programación la vista y el uso de la IBDesignable directiva. Esto fue específicamente para la gente que quería construir puntos de vista aunque visualmente. Yo no soy consciente de que una forma para crear una vista en un xib visualmente y tiene que ser prestados en un storyboard. No me sorprendería si esto será posible muy pronto, aunque si no lo es ya.
    • gracias… Esto me ha salvado la vida, pero tener que hacer en la SB a la hora de insertar el punto de vista hubiera sido hermoso 😉
    • Gran explicación! Pero tengo una sugerencia para ti: Uso UINib(nibName: nibName, bundle: nil).instantiateWithOwner(nil, options: nil) que es más rápido que el NSBundle-Versión.
    • Esto parece satisfacer el requisito de que usted puede diseñar en IB y han dibujado en el guión gráfico. Básicamente, hacer exactamente lo que hizo para el XIB y poner @IBDesignable on the class. que tienen Que implementar init(frame:) así -, pero aparte de que funciona bastante bien! supereasyapps.com/blog/2014/12/15/…
    • No se supone que vas a asignar el loadNibNamed:owner:options:‘s valor de retorno para self.view?
    • También, un tipo que dice que no se debe agregar a las restricciones de tamaño en la subclase, y tiene sentido, ya que el padre siempre se establece es subvistas.
    • Esto salvó mi día!!!

  3. 47

    Swift 3&4 Actualización a la aceptación de la respuesta

    1. Crear un nuevo UIView llamado ‘DesignableXibView’

    • Archivo > Nuevo > Archivo > Fuente > Cocoa Touch Clase > UIView

    2. Crear una coincidencia xib archivo llamado ‘DesignableXibView’

    • Archivo > Nuevo > Archivo > Interfaz de Usuario > Ver

    3. Configurar el archivo de propietario de la de la xib

    Seleccione el «DesignableXibView.xib» > «Dueño del Archivo» > se establece la «Costumbre de la Clase» a «DesignableXibView’ en la Identidad del Inspector.

    • Nota: no configure la clase personalizada de la vista en el xib. Sólo el
      El Propietario Del Archivo!

    4. DesignableXibView Implementación del

        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 Prueba de su reutilizables ver en un storyboard

    • Abrir su guión

    • Agregar una vista

    • Conjunto que ver la Clase Personalizada

    • No puedo conseguir que funcione en Xcode8/Swift3. Funciona bien cuando se ejecuta la aplicación, pero no se muestran en el guión gráfico.
    • Funciona muy bien para mí. Si usted está tratando de ver los cambios en la xib no se mostrará. Agregar una vista dentro de otro controlador y, a continuación, establezca la clase de que ver a DesignableXibView. Construir el proyecto para ver los cambios.
    • Trabajó también para mí. Sólo se necesita agregar el DesignableXibView a mi actual storyboard como se describe en el Paso 5 de Garfbargle post
    • ha funcionado, gracias!
    • Me acaba de llegar «no se Puede cargar PUNTA en paquete», en tiempo de ejecución?
    • Supongo que usted no puede utilizar String(describiendo: auto) de forma segura. El valor predeterminado es de un largo de depuración descripción de la atm. Que el código no era el futuro seguro..?
    • Creo que String(describing: type(of: self)) debe hacer esto de manera segura
    • En XCode 9.2 con el fin de obtener la xib para mostrar en el Guión gráfico tuve que crear la contentView como una salida no sólo una variable. Los ejemplos no demuestran esto. De lo contrario, sólo quiero ver a mi vista cuando me encontré con la aplicación.
    • No lo he comprobado en XCode 9.2, ya que hay informes de errores en esa versión, especialmente durante la carga binaria en la App Store. Y para mí, esto parece un error.

  4. 11

    La initWithCoder función en swift 2 si alguien está teniendo 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]))
        }
    
    • Gracias! Es posible que desee agregar un ejemplo de no usar el VFL, para aquellos que no quieren usar.
  5. 2

    Para cualquier persona tratando de adaptar aceptado la respuesta (por @Garfbargle) a Objective-C

    Sólo la conversión de Swift a Objective-C no es suficiente para hacer que funcione. He tenido tiempo para permitir vivir de representación en el Guión gráfico.

    Después de traducir el código en su totalidad, la vista es bien cargado cuando se ejecuta en el dispositivo (o simulador), sino de vivir de representación en el Guión no funciona. La razón para esto es que he utilizado [NSBundle mainBundle] mientras que el Interface Builder, no tiene acceso a mainBundle. Lo que usted tiene que utilizar en su lugar [NSBundle bundleForClass:self.classForCoder]. BOOM, viva representación de obras ahora !

    Nota : si tiene problemas con el Diseño Automático, pruebe a deshabilitar Safe Area Layout Guides en el Xib.

    Para su comodidad, os dejo mi código en su totalidad aquí, así que sólo tienes que copiar/pegar (para todo el proceso, siga 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
    

    Decirme si se encuentra con algunos problemas, pero se debe trabajar fuera de la caja 🙂

  6. 0

    Si alguien está interesado, aquí está el Xamarin.iOS versión de el código del 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);
            }
        }
    
  7. 0

    He aquí la respuesta que te he querido. Usted puede crear su CustomView clase, tiene el maestro de instancia en un xib con todas las subvistas y puntos de venta. A continuación, puede aplicar esa clase con todas las instancias en sus guiones o otros xibs.

    Sin necesidad de trastear con el Propietario del Archivo, o conectar las salidas de un proxy o modificar el xib de una manera peculiar, o agregar una instancia de la vista personalizada como una subvista de sí mismo.

    Basta con hacer:

    1. De importación BFWControls marco
    2. Cambiar su superclase de UIView a NibView (o de UITableViewCell a NibTableViewCell)

    Que es!

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

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

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

    Tom 👣

Dejar respuesta

Please enter your comment!
Please enter your name here