ios - represented - ¿Puede agregar propiedades IBDesignable a UIView usando categorías/extensiones?
ibinspectable swift 4 (5)
@IBDesignable funciona con la extensión UIView solo en la clase personalizada. Por ejemplo. UILabel es una subclase por defecto de UIView. No funcionará allí, pero si creas una clase personalizada llamada MyUILabel subclasificando UILabel. asigne la clase MyUILabel a la etiqueta en la que está trabajando. Entonces su radio de esquina en la extensión UIView funcionará de esta MyUILabel. (Supongo que la primera semana que te funciona es porque estás tratando con una clase personalizada).
Para aquellos que no saben de qué estoy hablando, Xcode 6.0 agregó nuevas características, IBDesignable e IBInspectable.
Al etiquetar sus vistas personalizadas con las propiedades de IBInspectable, esas propiedades aparecen en el inspector de atributos en IB.
Del mismo modo, cuando etiqueta una subclase UIView personalizada con IBDesignable, Xcode compila sus vistas e invoca el código para representar sus objetos de vista directamente en la ventana de Xcode para que pueda ver cómo se ven.
La técnica para agregar los atributos IBDesignable e IBInspectable a las vistas personalizadas es prácticamente idéntica en Swift y Objective-C. Las propiedades de IBInspectable aparecen en el inspector de atributos de Interface Builder, independientemente del idioma que utilice para definirlas.
He creado una categoría de UIView en Objective-C y una extensión de UIView en Swift que promueve las propiedades borderWidth, cornerRadius, borderColor y layerBackgroundColor de la capa subyacente de la vista como propiedades de la vista. Si cambia la propiedad, la extensión / categoría realiza la conversión de tipo según sea necesario y reenvía el cambio a la capa.
La parte IBInspectable funciona muy bien. Veo y puedo establecer las nuevas propiedades en el inspector de atributos de IB.
Podría haber jurado que la semana pasada, el atributo IBDesignable en mi categoría / extensión de vista también funcionó, y pude ver mi representación de categoría UIView personalizada en IB con los atributos de capa modificados. Esta semana no está funcionando.
Estaba alucinando?
¿Pueden las categorías / extensiones de las clases de sistemas existentes dibujar su IU personalizada en el Interface Builder cuando se configuran con IBDesignable?
Desde que publiqué esta pregunta, he aprendido que @IBDesignable no funciona para las extensiones de clase. Puedes agregar la etiqueta, pero no tiene efecto.
Este bloque de código está funcionando bien para mí.
import UIKit
public extension UIView {
@IBInspectable public var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
}
NOTA Es posible que no funcione cuando se importa desde un marco. Estoy tratando de averiguar la razón ahora.
He hecho este trabajo para mi caso de uso al tener una UIView @IBDesignable que configuré como vista superior en mi controlador de vista. Mi caso de uso particular es hacer que el estilo de ClassyKit sea visible en Interface Builder en las vistas predeterminadas de UIKit sin tener que subclasificar solo para eso y está funcionando muy bien.
Aquí hay un ejemplo de cómo podría configurarlo:
// in Interface Builder set the class of your top view controller view to this
@IBDesignable class DesignableView: UIView {
}
extension UIView {
open override func prepareForInterfaceBuilder() {
subviews.forEach {
$0.prepareForInterfaceBuilder()
}
}
}
extension UILabel {
// just an example of doing something
open override func prepareForInterfaceBuilder() {
layer.cornerRadius = 8
layer.masksToBounds = true
backgroundColor = .red
textColor = .green
}
}
Pude hacerlo funcionar con el código siguiente, pero el efecto secundario es que algunas veces el agente de IB en el guión gráfico se bloquea porque tiene que actualizar demasiados elementos de la interfaz de usuario. El reinicio de Xcode soluciona el problema temporalmente hasta la próxima caída. Tal vez ese es el problema al que se enfrenta OP
@IBDesignable
extension UIView
{
@IBInspectable
public var cornerRadius: CGFloat
{
set (radius) {
self.layer.cornerRadius = radius
self.layer.masksToBounds = radius > 0
}
get {
return self.layer.cornerRadius
}
}
@IBInspectable
public var borderWidth: CGFloat
{
set (borderWidth) {
self.layer.borderWidth = borderWidth
}
get {
return self.layer.borderWidth
}
}
@IBInspectable
public var borderColor:UIColor?
{
set (color) {
self.layer.borderColor = color?.cgColor
}
get {
if let color = self.layer.borderColor
{
return UIColor(cgColor: color)
} else {
return nil
}
}
}
}
Es por eso que estoy tratando de agregar la cláusula where para reducir las subclases que deberían extender esta funcionalidad: Genérico IBDesginables UIView extensión