열거 형 유형의 IBInspectable을 만드는 방법


83

enum인터페이스 빌더가 정의한 런타임 속성 이 아닙니다 . 다음은 Interface Builder의 Attributes Inspector에 표시되지 않습니다.

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

설명서 에서 : 부울, 정수 또는 부동 소수점 숫자, 문자열, 지역화 된 문자열, 사각형 등 Interface Builder 정의 런타임 속성에서 지원하는 모든 유형의 클래스 선언, 클래스 확장 또는 범주의 모든 속성에 IBInspectable 속성을 연결할 수 있습니다. , 포인트, 크기, 색상, 범위 및 nil.

Q :enum Interface Builder의 Attributes Inspector에서 어떻게 볼 수 있습니까?


1
그 목록에서 열거 형은 어디에 있습니까? 열거 형을 사용할 수있는 이유는 무엇입니까?
Paulw11 2014

13
enum내가 생각하는 IB에서 직접 케이스 를 선택 하거나 UIFont네이티브 UIKit 객체가 할 수있는 것처럼.
SwiftArchitect 2015 년

답변:


76

스위프트 3

@IBInspectable은 var shape:StatusShape = .Rectangle 단순히 Interface Builder에 빈 항목을 만듭니다.

IB에서는 사용할 수 없음

Swift와 Interface Builder 사이 의 다리 역할을하는 어댑터를 사용하십시오 .
shapeAdapterIB에서 검사 가능 :

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

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 에서이 솔루션을 찾으십시오 .


shapeAsInt계산 된 속성이 아닌 저장된 속성으로 유지하는 이유는 무엇 입니까?
nhgrif

권리. writeonly그래도 속성을 만들 수는 없지만 계산 된 속성은 저장된 속성처럼 백업 인스턴스 변수를 만들지 않습니다.
nhgrif

@nhgrif가 제안한 비 백업 스토어 솔루션을 추가했습니다 .
SwiftArchitect

1
내 반대표를 실례합니다. TARGET_INTERFACE_BUILDER에 대한 작업 솔루션이 있다고 생각했지만 잘못되었습니다. 죄송합니다. 여기에 행운을 빕니다
Dan Rosenstark

2017 년으로 빨리 감기이 문제는 여전히 동일하게 유지됩니까?
NoSixties

41

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에 초기화를 추가하여도 목표 -C 직장이 얻을 수있다. 그러나 컴파일러는 신속한 코드에서 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
        }
    }
}

2
나는 Swift Only버전을 좋아한다 : 그것은 IB 에서 평범한 영어를 허용한다 .
SwiftArchitect

누구든지이 방법을 사용하여 IB의 문자열 드롭 다운으로 표시되는 옵션을 얻는 방법을 알고 있습니까?
airowe

가능한 경우 드롭 다운을 사용하여이 작업을 수행하는 방법을 알고 싶습니다.
Wael

19

빠른 구문을 기억할 수 없지만 이것이 obj-c에서 해결 한 방법입니다.

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

1
조건부 어셈블리가있는 유일한 위치는 선언의 한 지점입니다. 열거 형은 obj-c의 정수 값이므로 다른 곳에서는 조건부 어셈블리가 없습니다. 한 자리는 사과 수정이 (그들은 것입니다 가정.) 때 제거하는 방법
제이슨 Bobier에게

이는 재치와 멋진 솔루션이며, 여기에 언급 nshipster.com/ibinspectable-ibdesignable
댄 Rosenstark는

7

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

그리고 사용의 예 ...

switch side {
    case .left:
        textColor = .red
    case .right:
        textColor = .green
    }

이 중요한 Swift / iOS QA를 위해

• @SwiftArchitect의 아주 오래된 답변은 완벽하게 정확하지만

• 방금 업데이트하고 중요한 "사용할 수없는"항목을 추가했습니다. 이제 Swift에서 가능합니다.


4

이것은 오래된 스레드이지만 유용합니다. 나는 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

2

SwiftArchitect 기반의 Swift 3 솔루션

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

2
이 IB 검사 가능 속성을 #if TARGET_INTERFACE_BUILDER블록 에 래핑하면 런타임이 아닌 Interface Builder의 렌더링에만 영향을줍니다. 이로 인해 예기치 않은 동작이 발생할 수 있으며 항상 콘솔에 경고가 표시됩니다.Failed to set (statusShapeIB) user defined inspected property ...: this class is not key value coding-compliant for the key statusShapeIB.
Mischa
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.