web-dev-qa-db-ja.com

列挙型のIBInspectableを作成する方法

enumnot Interface Builderで定義されたランタイム属性です。以下は、Interface BuilderのAttributes Inspectorには表示されません。

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

ドキュメントから:IBInspectable属性は、Interface Builderで定義されたランタイム属性でサポートされているタイプのクラス宣言、クラス拡張、またはカテゴリのプロパティに添付できます:ブール、整数、または浮動小数点数、文字列、ローカライズされた文字列、長方形、ポイント、サイズ、色、範囲、およびnil

Q: Interface BuilderのAttributes Inspectorでenumを表示するにはどうすればよいですか?

73
SwiftArchitect

スイフト3

@ IBInspectablevar shape:StatusShape = .Rectangleは、Interface Builderで空のエントリを作成するだけです:

Not available in IB

アダプタを使用します。これは、SwiftとInterface Builderの間のbridgeブリッジとして機能します。
shapeAdapterは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

条件付きコンパイルアプローチ(#if TARGET_INTERFACE_BUILDERを使用)とは異なり、shape変数のタイプはターゲットによって変更されないため、shape:NSIntegershape:StatusShapeのバリエーションに対処するためにソースコードをさらに変更する必要があります。

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

完全なコード

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

GitHub でこのソリューションを見つけます。

69
SwiftArchitect

検査可能な列挙型を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
        }
    }
}

また、enumに初期化子を追加することで、これをObjective-cでも動作させることができますis。ただし、コンパイラはSwiftコードでIBのみのプロパティの「使用不可」エラーのみを表示します。

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
        }
    }
}
36
DonVaughn

Swift構文を思い出せませんが、これがobj-cでの解決方法です

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

これは古いスレッドですが、便利です。私は私の答えをSwift 4.0とXcode 9.0に適応させました-Swift 4にはこの問題に関する小さな問題があります。列挙型の@IBInspectable変数を持っていますタイプとXcode 9.0は満足しておらず、「そのタイプはObjective-cで表すことができないため、プロパティを@IBInspectableとしてマークすることはできません」と表示されます

@Eporedieseは(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
3
Ohmy

Swift 3SwiftArchitect に基づくソリューション

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
1
Eporediese
I just removed @IBInspectable keyword 

そのエラーが表示された場所から(私にとっては2回でした)。変更するには、VHBoomMenuButtonライブラリのロックを解除する必要があります。

and its work  
0
Shakeel Ahmed