Interface Builder, @IBOutlet y protocolos para delegado y dataSource en Swift
interface-builder (6)
De las notas de lanzamiento de Xcode:
Interface Builder no admite la conexión a una salida en un archivo Swift cuando el tipo de salida es un protocolo.
Solución alternativa: declare el tipo de salida como AnyObject o NSObject, conecte los objetos a la salida utilizando Interface Builder y luego cambie el tipo de salida al protocolo.
EDITAR: Las notas de lanzamiento de Xcode 9 beta 3 dicen que esta solución ya no debería ser necesaria.
No se puede conectar la propiedad delegada de CustomView
declarada como @IBOutlet a ViewController
en Interface Builder, simplemente no se puede establecer una conexión.
Aquí está el código
class CustomView: UIView {
@IBOutlet var delegate: CustomViewDelegate?
}
@objc protocol CustomViewDelegate {
...
}
class ViewController: UIViewController, CustomViewDelegate {
...
}
@objc
se usa debido al protocolo swift, la propiedad IBOutlet no puede tener un tipo que no sea un objeto , no sé por qué el protocol CustomViewDelegate: class {}
no funciona.
¿Alguien más se encontró con algo así?
Este es un hilo antiguo, pero pensé que me gustaría señalar que a partir de Xcode 9 beta 3, ahora es posible conectar un delegado personalizado escrito en swift para crear interfaces.
Según las notas de publicación.
Interface Builder ahora reconoce salidas, acciones y propiedades inspeccionables declaradas en clases que tienen una extensión de protocolo Swift. (22201035)
// Can connect this to interface builder now
class MyViewController: UIViewController {
@IBOutlet weak var myDelegate: TheNewDelegate?
}
Otro que no es bonito pero:
@IBOutlet weak var ibDelegate: NSObject?
@IBOutlet weak var ibDataSource: NSObject?
var delegate: MultipleButtonViewDelegate? { return ibDelegate as? MultipleButtonViewDelegate }
var dataSource: MultipleButtonViewDataSource? { return ibDataSource as? MultipleButtonViewDataSource }
Para mí, el motivo fue que la vista de tabla era nil
en el punto en el que intenté establecer su fuente de datos y delegar. Esto se debió a que el inicializador designado initWithNibName:bundle:
que no garantiza las conexiones inicializadas . Aplazar la configuración de mi fuente de datos y delegado a viewDidload
funcionó a la viewDidload
.
Una solución elegante :
#if TARGET_INTERFACE_BUILDER
@IBOutlet open weak var delegate: AnyObject?
#else
open weak var delegate: CustomViewDelegate?
#endif
Consulte: https://github.com/WenchaoD/FSPagerView/blob/master/Sources/FSPagerView.swift#L88
Adam Waite proporciona una buena solución. Sin embargo, prefiero la siguiente solución, ya que enfatiza la solución y la propiedad adicional también se puede eliminar una vez que Xcode se solucione.
class CustomView: UIView {
@IBOutlet
public var delegate: CustomViewDelegate?
/// Workaround for Xcode bug that prevents you from connecting the delegate in the storyboard.
/// Remove this extra property once Xcode gets fixed.
@IBOutlet
public var ibDelegate: AnyObject? {
get { return delegate }
set { delegate = newValue as? CustomViewDelegate }
}
func someMethod() {
// Here we always refer to `delegate`, not `ibDelegate`
delegate?.onSomethingHappened()
}
}
@objc protocol CustomViewDelegate {
...
}
Oye, ¿este bicho ya tiene un año y medio?