열거 형 유형의 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:NSInteger대 shape: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.