for features ios xcode swift interface-builder

features - xcode version for ios 12



Cómo crear un IBInspectable de tipo enum (6)

enum no es un atributo de tiempo de ejecución definido de Interface Builder. Lo siguiente no se muestra en el Inspector de Atributos de Interface Builder:

enum StatusShape:Int { case Rectangle = 0 case Triangle = 1 case Circle = 2 } @IBInspectable var shape:StatusShape = .Rectangle

De la documentación: Puede adjuntar el atributo IBInspectable a cualquier propiedad en una declaración de clase, extensión de clase o categoría para cualquier tipo que sea compatible con los atributos de tiempo de ejecución definidos de Interface Builder: booleano, entero o número de punto flotante, cadena, cadena localizada, rectángulo , punto, tamaño, color, rango y nada.

P: ¿Cómo puedo ver una enum en el Inspector de atributos de Interface Builder?


Swift 3

@IBInspectable var shape:StatusShape = .Rectangle simplemente crea una entrada en blanco en Interface Builder:

Use un adaptador, que actuará como un puente entre Swift e Interface Builder.
shapeAdapter es inspeccionable desde IB:

// IB: use the adapter @IBInspectable var shapeAdapter:Int { get { return self.shape.rawValue } set( shapeIndex) { self.shape = StatusShape(rawValue: shapeIndex) ?? .Rectangle } }

A diferencia del enfoque de compilación condicional (usando #if TARGET_INTERFACE_BUILDER ), el tipo de variable de shape no cambia con el objetivo, lo que posiblemente requiera más cambios en el código fuente para hacer frente a la shape:NSInteger vs. shape:StatusShape variaciones de shape:StatusShape :

// Programmatically: use the enum var shape:StatusShape = .Rectangle

Código completo

@IBDesignable class ViewController: UIViewController { enum StatusShape:Int { case Rectangle case Triangle case Circle } // Programmatically: use the enum var shape:StatusShape = .Rectangle // IB: use the adapter @IBInspectable var shapeAdapter:Int { get { return self.shape.rawValue } set( shapeIndex) { self.shape = StatusShape(rawValue: shapeIndex) ?? .Rectangle } } }

► Encuentre esta solución en GitHub .


En lugar de establecer sus enumeraciones inspeccionables con entradas, también puede configurarlas con cadenas. Aunque no es tan preferible como un menú desplegable, al menos esta opción ofrece cierto nivel de legibilidad.

Opción Swift-only:

// 1. Set up your enum enum Shape: String { case Rectangle = "rectangle" // lowercase to make it case-insensitive case Triangle = "triangle" case Circle = "circle" } // 2. Then set up a stored property, which will be for use in code var shape = Shape.Rectangle // default shape // 3. And another stored property which will only be accessible in IB (because the "unavailable" attribute prevents its use in code) @available(*, unavailable, message: "This property is reserved for Interface Builder. Use ''shape'' instead.") @IBInspectable var shapeName: String? { willSet { // Ensure user enters a valid shape while making it lowercase. // Ignore input if not valid. if let newShape = Shape(rawValue: newValue?.lowercased() ?? "") { shape = newShape } } }

También es posible hacer que esto funcione con objetivo-c añadiendo un inicializador a la enumeración. Sin embargo, el compilador solo mostrará el error "no disponible" para sus propiedades solo IB en código rápido.

Opción Swift con compatibilidad Obj-C:

@objc enum Shape: Int { case None case Rectangle case Triangle case Circle init(named shapeName: String) { switch shapeName.lowercased() { case "rectangle": self = .Rectangle case "triangle": self = .Triangle case "circle": self = .Circle default: self = .None } } } var shape = Shape.Rectangle // default shape @available(*, unavailable, message: "This property is reserved for Interface Builder. Use ''shape'' instead.") @IBInspectable var shapeName: String? { willSet { if let newShape = Shape(rawValue: newValue?.lowercased() ?? "") { shape = newShape } } }


Este es un hilo viejo pero útil. He adaptado mi respuesta a swift 4.0 y Xcode 9.0 - Swift 4 tiene sus propios pequeños problemas con este problema. Estoy teniendo una variable @IBInspectable con el tipo enum y Xcode 9.0 no está contento, mostrándome esto "La propiedad no se puede marcar @IBInspectable porque su tipo no se puede representar en Objective-c"

@Eporediese responde a este problema (para swift3) en parte; usando una propiedad para el guión gráfico pero una enumeración directa para el resto del código. A continuación se muestra un conjunto de códigos más completo que le da una propiedad para trabajar en ambos casos.

enum StatusShape: Int { case Rectangle = 0 case Triangle = 1 case Circle = 2 } var _shape:StatusShape = .Rectangle // this is the backing variable #if TARGET_INTERFACE_BUILDER @IBInspectable var shape: Int { // using backing variable as a raw int get { return _shape.rawValue } set { if _shape.rawValue != newValue { _shape.rawValue = newValue } } } #else var shape: StatusShape { // using backing variable as a typed enum get { return _shape } set { if _shape != newValue { _shape = newValue } } } #endif


No puedes. Si desea que esté disponible en Interface Builder, haga que su propiedad sea uno de los tipos admitidos. En este caso, conviértalo en int y échalo a tu tipo de enumeración en el código.


No puedo recordar la sintaxis rápida, pero así es como lo resolví en obj-c

#if TARGET_INTERFACE_BUILDER @property (nonatomic) IBInspectable NSInteger shape; #else @property (nonatomic) StatusShape shape; #endif


Solución Swift 3 basada en SwiftArchitect

enum StatusShape: Int { case rectangle, triangle, circle } var statusShape: StatusShape = .rectangle #if TARGET_INTERFACE_BUILDER @IBInspectable var statusShapeIB: Int { get { return statusShape.rawValue } set { guard let statusShape = StatusShape(rawValue: newValue) else { return } self.statusShape = statusShape } } //convenience var, enum not inspectable #endif