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