如何创建类型枚举的IBInspectable

Swi*_*ect 74 xcode interface-builder ios swift

enum接口生成器中定义的运行时属性.Interface Builder的Attributes Inspector中未显示以下内容:

enum StatusShape:Int {
    case Rectangle = 0
    case Triangle = 1
    case Circle = 2
}
@IBInspectable var shape:StatusShape = .Rectangle
Run Code Online (Sandbox Code Playgroud)

从文档: 您可以将IBInspectable属性附加到类声明,类扩展或类别中的任何属性,以用于Interface Builder定义的运行时属性支持的任何类型:布尔值,整数或浮点数,字符串,本地化字符串,矩形,点,大小,颜色,范围和零.

问:如何enum在Interface Builder的Attributes Inspector中看到?

Swi*_*ect 70

斯威夫特3

@IBInspectable var shape:StatusShape = .Rectangle只在Interface Builder中创建一个空白条目:

不适用于IB

使用适配器,它将充当Swift和Interface Builder之间的桥梁.
shapeAdapter可以从IB检查:

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

可在IB中使用

不同于(使用条件编译方法#if TARGET_INTERFACE_BUILDER),所述的类型shape变量不与目标改变,可能需要进一步修改源代码,以应付shape:NSIntegershape:StatusShape变体:

   // Programmatically: use the enum
   var shape:StatusShape = .Rectangle
Run Code Online (Sandbox Code Playgroud)

完整的代码

@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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

►在GitHub上找到此解决方案.


Don*_*ghn 36

您也可以使用字符串设置它们,而不是使用整数设置可检查的枚举.尽管不如下拉列表那样优先,但至少这个选项提供了一定程度的可读性.

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

可能的也是获得此与Objective-C的工作,以及通过增加一个初始化的枚举.但是,编译器只会在swift代码中为您的仅IB属性显示"不可用"错误.

具有Obj-C兼容性的Swift选项:

@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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢"Swift Only"版本:它允许**IB**中的普通英语. (2认同)

小智 20

我不记得swift语法,但这就是我在obj-c中解决它的方法

#if TARGET_INTERFACE_BUILDER
@property (nonatomic) IBInspectable NSInteger shape;
#else
@property (nonatomic) StatusShape shape;
#endif
Run Code Online (Sandbox Code Playgroud)


Fat*_*tie 6

对于 2020 年 - 今天更新了@SwiftArchitect 答案:

这是一个典型的完整示例,包含当今所有的语法

在此处输入图片说明

import UIKit

@IBDesignable class ClipLabels: UILabel {
    
    enum Side: Int { case left, right }
    
    var side: Side = .left {
        didSet {
            common()
        }
    }
    
    @available(*, unavailable, message: "IB only")
    @IBInspectable var leftRight01: Int {
        get {
            return self.side.rawValue
        }
        set(index) {
            self.side = Side(rawValue: index) ?? .left
        }
    }
    
Run Code Online (Sandbox Code Playgroud)

并且只是一个使用示例......

switch side {
    case .left:
        textColor = .red
    case .right:
        textColor = .green
    }
Run Code Online (Sandbox Code Playgroud)

对于这个关键的 Swift/iOS QA,

•@SwiftArchitect 的非常古老的答案是完全正确的,但是

• 我刚刚更新了它并添加了关键的“不可用”的东西,现在可以在 Swift 中实现。