Ios 如何创建enum类型的IBInspectable

Ios 如何创建enum类型的IBInspectable,ios,xcode,swift,interface-builder,Ios,Xcode,Swift,Interface Builder,enum不是接口生成器定义的运行时属性。 以下内容不会显示在界面生成器的属性检查器中: enum StatusShape:Int { case Rectangle = 0 case Triangle = 1 case Circle = 2 } @IBInspectable var shape:StatusShape = .Rectangle 从文件中: 对于接口生成器定义的运行时属性支持的任何类型,可以将IBInspectable属性附加到类声明、类扩展或类别中的任何属

enum
不是接口生成器定义的运行时属性。 以下内容不会显示在界面生成器的属性检查器中:

enum StatusShape:Int {
    case Rectangle = 0
    case Triangle = 1
    case Circle = 2
}
@IBInspectable var shape:StatusShape = .Rectangle
从文件中: 对于接口生成器定义的运行时属性支持的任何类型,可以将IBInspectable属性附加到类声明、类扩展或类别中的任何属性:布尔值、整数或浮点数、字符串、本地化字符串、矩形、点、大小、颜色、范围和零

Q:如何在Interface Builder的属性检查器中查看
enum
@IBInspectable
var shape:StatusShape=.Rectangle
仅在Interface Builder中创建一个空白条目:

使用适配器,它将充当Swift和Interface Builder之间的桥梁。
shapedapter
可从IB进行检查:

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

与条件编译方法(使用
#if TARGET\u INTERFACE\u BUILDER
)不同,
shape
变量的类型不会随目标而改变,可能需要进一步的源代码更改以应对
shape:NSInteger
shape:StatusShape
的变化:

   // Programmatically: use the enum
   var shape:StatusShape = .Rectangle
完整代码
► 在上找到此解决方案。

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

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

您也可以使用字符串来设置可检查的枚举,而不是使用int来设置它们。尽管不像下拉菜单那么可取,但至少该选项提供了一定程度的可读性

仅Swift选项:

// 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
        }
    }
}
通过向枚举中添加初始值设定项,也可以将其用于objective-c。但是,编译器只会在swift代码中显示仅IB属性的“不可用”错误

Swift选项与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
        }
    }
}
Swift 3 基于

enum StatusShape:Int{
长方形、三角形、圆形
}
变量statusShape:statusShape=.rectangle
#如果目标\u接口\u生成器
@IBInspectable var statusShapeIB:Int{
获取{
返回statusShape.rawValue
}
集合{
guard let statusShape=statusShape(rawValue:newValue)else{return}
self.statusShape=statusShape
}
}//方便变量,枚举不可检查
#恩迪夫

这是一个旧线程,但很有用。我已经将我的答案改编为swift 4.0和Xcode 9.0-swift 4在这个问题上有自己的小问题。我有一个枚举类型为@IBInspectable的变量,Xcode 9.0不满意,向我显示“属性不能标记为@IBInspectable,因为它的类型不能在Objective-c中表示”

@ePrediese部分解决了这个问题(针对swift3);对情节提要使用属性,但对其余代码使用直接枚举。下面是一个更完整的代码集,它为您提供了在这两种情况下都可以使用的属性

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
2020年-@SwiftArchitect今天更新的答案: 下面是一个典型的完整示例,介绍了当今的所有语法

这只是一个使用的例子

switch side {
    case .left:
        textColor = .red
    case .right:
        textColor = .green
    }
对于这一关键的Swift/iOS QA

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


•我刚刚更新了它,并添加了关键的“不可用”内容,这在Swift中现在是可能的。

该列表中的enum在哪里?为什么你会认为你可以使用枚举?我想,如果能直接从IB中选择一个
enum
大小写,或者像本机UIKit对象一样选择一个
UIFont
,那就太好了。为什么你要将
shapeAsInt
保留为存储属性而不是计算属性?对。但是,您不能将属性
写入
。。。但是计算属性不像存储属性那样创建支持实例变量。添加了@nhgrif建议的无支持存储解决方案。请原谅我的否决票。我原以为我和TARGET_INTERFACE_BUILDER有一个可行的解决方案,但我被误导了。对不起,祝你好运,在2017年的最后一天,这个问题是否仍然保持不变?我唯一有条件集会的地方就是宣言中的那一点。由于枚举是obj-c中的整数值,因此在其他任何地方都没有条件程序集。当苹果解决这个问题时(假设他们会的话)需要去掉一个点。这是一个机智而令人敬畏的解决方案,这里提到的我喜欢
Swift Only
版本:它允许在IB中使用纯英语。有人知道如何使用此方法在IB中获得字符串下拉列表形式的选项吗?我想知道如果可能,如何使用下拉列表完成此操作。如果您将此IB可检查属性包装在
中#如果目标界面构建器
阻止它只会影响界面构建器中的渲染,而不会影响运行时的渲染。这可能会导致意外行为,并且您将始终在控制台中收到警告:
设置(statusShapeIB)用户定义的已检查属性失败…:此类不符合key statusShapeIB的键值编码。
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
        }
    }
    
switch side {
    case .left:
        textColor = .red
    case .right:
        textColor = .green
    }