How to create an IBInspectable of type enum

前端 未结 6 1443
遇见更好的自我
遇见更好的自我 2020-12-04 11:56

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



        
6条回答
  •  天命终不由人
    2020-12-04 12:32

    Instead of setting your inspectable enums with ints, you could also set them with strings. Although not quite as preferable as a dropdown, at least this option offers some level of readability.

    Swift-only Option:

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

    It is possible to also get this to work with objective-c as well, by adding an initializer to the enum. However, the compiler will only show the "unavailable" error for your IB-only properties in swift code.

    Swift Option with Obj-C Compatibility:

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

提交回复
热议问题