How to create an IBInspectable of type enum

SwiftArchitect picture SwiftArchitect · Dec 11, 2014 · Viewed 28.7k times · Source

enum is not an Interface Builder defined runtime attribute. The following does not show in Interface Builder's Attributes Inspector:

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

From the documentation: You can attach the IBInspectable attribute to any property in a class declaration, class extension, or category for any type that’s supported by the Interface Builder defined runtime attributes: boolean, integer or floating point number, string, localized string, rectangle, point, size, color, range, and nil.

Q: How can I see an enum in Interface Builder's Attributes Inspector?

Answer

SwiftArchitect picture SwiftArchitect · Dec 12, 2014

Swift 3

@IBInspectable var shape:StatusShape = .Rectangle merely creates a blank entry in Interface Builder:

Not available in IB

Use an adapter, which will acts as a bridge between Swift and Interface Builder.
shapeAdapter is inspectable from IB:

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

Available in IB

Unlike the conditional compilation approach (using #if TARGET_INTERFACE_BUILDER), the type of the shape variable does not change with the target, potentially requiring further source code changes to cope with the shape:NSInteger vs. shape:StatusShape variations:

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

Complete code

@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
        }
    }
}

► Find this solution on GitHub.