Subclase de UIView personalizada desde un archivo xib
Vistas personalizadas con outlets & acciones
Así que la forma correcta de cargar vistas personalizadas desde archivos xib es algo así:
Dentro de tu objeto de vista personalizada, instancias el archivo xib exactamente de la misma forma que te dije aquí arriba. 👆 La única diferencia es que no necesitas usar el array de objetos devuelto por los métodos, sino que tienes que conectar tus objetos de vista a través del constructor de interfaces, usando el Propietario del archivo como punto de referencia, más una salida de vista de contenedor personalizado, que contendrá todo lo que necesitas. 🤨
// note: view object is from my previous tutorial, with autoresizing masks disabledclass CustomView: View { // this is going to be our container object @IBOutlet weak var containerView: UIView! // other usual outlets @IBOutlet weak var textLabel: UILabel! override func initialize() { super.initialize() // first: load the view hierarchy to get proper outlets let name = String(describing: type(of: self)) let nib = UINib(nibName: name, bundle: .main) nib.instantiate(withOwner: self, options: nil) // next: append the container to our view self.addSubview(self.containerView) self.containerView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate() }}
Así que el método initialize aquí es sólo cargar el archivo nib con el propietario de self. Después de que el proceso de carga terminó, sus punteros de salida van a ser llenados con los valores apropiados del archivo xib. Hay una última cosa que tenemos que hacer. Incluso las vistas del archivo xib están conectadas «programáticamente» a nuestro objeto vista personalizado, pero visualmente no lo están. Así que tenemos que añadir nuestra vista contenedora en la jerarquía de vistas. 🤐
Si quieres usar tu objeto de vista personalizado, sólo tienes que crear una nueva instancia de él – dentro de un controlador de vista – y finalmente siéntete libre de añadirlo como una subvista!
Una palabra sobre bounds, frames aka. springs y struts: f*ckng UGLY! Son dos palabras. Son considerados como una mala práctica, así que por favor usen auto layout, tengo un buen tutorial sobre anclajes, son increíbles y aprenderlos toma unos 15 minutos. 😅
class ViewController: UIViewController { weak var customView: CustomView! override func loadView() { super.loadView() let customView = CustomView() self.view.addSubview(customView) NSLayoutConstraint.activate() self.customView = customView } override func viewDidLoad() { super.viewDidLoad() self.customView.textLabel.text = "Lorem ipsum" }}
Eso es todo, ahora tienes un objeto UIView personalizado completamente funcional que carga un archivo xib para poder usar su contenido. No ha estado tan mal, ¿verdad? 🤪
Una cosa más. Si no te gusta manejar las vistas de forma programática o simplemente no quieres complicarte con el método loadView, elimínalo por completo. A continuación, pon la palabra clave @IBOutlet justo antes de tu variable de clase de vista personalizada. Abre tu storyboard usando IB, luego arrastra & suelta un nuevo elemento UIView a tu controlador y conecta la salida de la vista personalizada. Debería funcionar como magia. 💫
Prometí salidas y acciones en el título de esta sección, así que vamos a hablar un poco de IBActions. Funcionan exactamente igual que las esperas con los controladores. Puedes simplemente enganchar un botón a tu vista personalizada y delegar la acción a la clase de la vista personalizada. Si quieres reenviar toques o acciones específicas a un controlador, debes usar el patrón delegado o ir con un simple bloque. 😎