@IBInspectable with enum?


86

@IBInspectable아래 그림과 같이 요소 를 만들고 싶습니다 .

여기에 이미지 설명 입력

내 생각은 enum과 같은 것을 유형으로 사용하는 @IBInspectable것이지만 그렇지 않은 것처럼 보입니다. 이와 같은 요소를 구현하는 방법에 대한 아이디어가 있습니까?

편집하다:

@IBInspectable다음 유형 만 지원하는 것 같습니다 .

  • Int
  • CGFloat
  • Double
  • String
  • Bool
  • CGPoint
  • CGSize
  • CGRect
  • UIColor
  • UIImage

부끄러워


해결 방법은 설정하려는 값 앞에 검사 가능한 계산 된 속성을 배치하는 것입니다. 물론, 여전히 Interface Builder에서 열거 된 값의 팝업 메뉴로 마술처럼 나타나지는 않습니다. 그러나 적어도 검사 가능한 값을 정의하고이를 사용하여 열거 형을 설정할 수 있습니다.
matt

8
올해 WWDC에서 저는 개발자 도구 연구실의 Apple 엔지니어에게 이에 대해 물었습니다. 그는 그것이 훌륭한 기능이 될 것이라는 데 동의했지만 현재는 불가능하다고 말했다. 그는 내가했던 bugreport.apple.com에 레이더를 제출할 것을 제안했습니다 . 문제 15505220의 중복으로 종결되었지만 비슷한 문제를 제기하는 사람들을 적극 권장합니다. 이러한 문제는 충분한 사람들이 불평하면 종종 해결됩니다.
Will Clarke



그리고 SwiftUI와 Xcode 11의 새로운 Canvas를 사용하면 Apple의 로드맵에 포함되지 않을 것 같습니다
Ben Leggiero 19

답변:


26

(현재로서는) 불가능합니다. 사용자 정의 런타임 속성 섹션에 표시되는 유형 만 사용할 수 있습니다 .

Apple의 문서에서 :

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


2
열거 형을 사용하고 싶을 때 열거 형 값에 명시 적 할당 (= 1, = 2 등)을 제공합니다. 그리고 핸들러에서 IB의 값이 열거 형의 값 중 하나가 아닌 경우 어설 션을 추가합니다. 열거 형이 지원되지 않는다는 것은 짜증나지만이 트릭은 적어도 더 유용하게 만듭니다.
Zev Eisenberg

열거 형은 정수입니다.
Amin Negm-Awad

23

이에 대한 또 다른 해결 방법은 열거 속성이 인터페이스 빌더에 표시되는 방식을 변경하는 것입니다. 예를 들면 :

#if TARGET_INTERFACE_BUILDER
@property (nonatomic, assign) IBInspectable NSInteger fontWeight;
#else
@property (nonatomic, assign) FontWeight fontWeight;
#endif

이것은 FontWeight라는 열거 형을 가정합니다. 열거 형과 원시 정수 값은 Objective-C에서 다소 상호 교환 적으로 사용할 수 있다는 사실에 의존합니다. 이 작업을 수행 한 후에는 이상적이지 않지만 작동하는 특성에 대해 인터페이스 빌더에서 정수를 지정할 수 있으며 동일한 특성을 프로그래밍 방식으로 사용할 때 소량의 유형 안전성을 유지합니다.

동일한 작업을 수행하는 데 사용할 수있는 두 번째 정수 속성을 처리하기 위해 추가 논리를 작성할 필요가 없기 때문에 별도의 정수 속성을 선언하는 것보다 더 나은 대안입니다.

그러나 이것은 정수에서 열거 형으로 암시 적으로 캐스트 할 수 없기 때문에 Swift에서는 작동하지 않습니다. 해결에 대한 모든 생각을 주시면 감사하겠습니다.


2
나는 이것이 Swift에서 작동한다고 생각했지만, 추가 테스트에서 ... 아니오
Dan Rosenstark 2015

7

Inspectable NSInteger 값을 사용하여이 작업을 수행하고 setter를 재정 의하여 열거 형을 설정할 수 있도록합니다. 여기에는 팝업 목록을 사용하지 않는 제한이 있으며 열거 형 값을 변경하면 인터페이스 옵션이 일치하도록 업데이트되지 않습니다.

예.

헤더 파일에서 :

typedef NS_ENUM(NSInteger, LabelStyle)
{
    LabelStyleContent = 0, //Default to content label
    LabelStyleHeader,
};

...

@property LabelStyle labelStyle;
@property (nonatomic, setter=setLabelAsInt:) IBInspectable NSInteger labelStyleLink;

구현 파일에서 :

- (void)setLabelAsInt:(NSInteger)value
{
    self.labelStyle = (LabelStyle)value;
}

선택적으로 거기에 논리를 추가하여 유효한 값으로 설정되었는지 확인할 수 있습니다.


왜 이것이 반대 투표인지 잘 모르겠습니다. 문제를 해결하는 좋은 방법 인 것 같습니다.
Fogmeister

실제로 순간에 응용 프로그램 내에서이 구현을 사용하고 있습니다 : - @Fogmeister 주셔서 감사합니다
마 콜리

4

Sikhapol은 정확하고 enum은 xCode 9에서도 지원되지 않습니다. 가장 안전한 방법은 enum을 문자열로 사용하고 "shadow"(개인) IBInspectable var를 구현하는 것입니다. 다음은 Interface Builder (swift 4) 내에서 사용자 정의 아이콘 (PaintCode를 사용하여 수행됨)으로 스타일을 지정할 수있는 바 버튼 항목을 나타내는 BarBtnPaintCode 항목의 예입니다.

인터페이스 빌드에서 문자열 (열거 형 값과 동일)을 입력하면 명확하게 유지됩니다 (숫자를 입력하는 경우 아무도 그 의미를 알 수 없습니다).

class BarBtnPaintCode: BarBtnPaintCodeBase {

    enum TypeOfButton: String {
        case cancel
        case ok
        case done
        case edit
        case scanQr
        //values used for tracking if wrong input is used
        case uninitializedLoadedFromStoryboard
        case unknown
    }

    var typeOfButton = TypeOfButton.uninitializedLoadedFromStoryboard

    @IBInspectable private var type : String {
        set {
            typeOfButton = TypeOfButton(rawValue: newValue) ?? .unknown
            setup()
        }
        get {
            return typeOfButton.rawValue
        }
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    init(typeOfButton: TypeOfButton, title: String? = nil, target: AnyObject?, action: Selector) {
        super.init()
        self.typeOfButton = typeOfButton
        setup()
        self.target = target
        self.action = action
        self.title  = title
    }

    override func setup() {
        //same for all
        setTitleTextAttributes([NSAttributedStringKey.font : UIFont.defaultFont(size: 15)],for: UIControlState.normal)
        //depending on the type
        switch typeOfButton {
        case .cancel  :
            title = nil
            image = PaintCode.imageOfBarbtn_cancel(language: currentVisibleLanguage)
        case .ok      :
            title = nil
            image = PaintCode.imageOfBarbtn_ok(language: currentVisibleLanguage)
        case .done    :
            title = nil
            image = PaintCode.imageOfBarbtn_done(language: currentVisibleLanguage)
        case .edit    :
            title = nil
            image = PaintCode.imageOfBarbtn_edit(language: currentVisibleLanguage)
        case .uninitializedLoadedFromStoryboard :
            title = nil
            image = PaintCode.imageOfBarbtn_unknown
            break
        case .unknown:
            log.error("BarBtnPaintCode used with unrecognized type")
            title = nil
            image = PaintCode.imageOfBarbtn_unknown
            break
        }

    }

}

Swift 4로 구현 된 환상적인 솔루션은 문제가 없습니다. 당신이 사용하는 경우 스토리 보드 및 xibs 제대로 맞춤법 유형의주의
MindBlower3

1

@sikhapol이 대답했듯이 이것은 불가능합니다. 이 문제를 해결하기 위해 사용하는 해결 방법은 IBInspectable클래스에 여러 부울을 포함하고 인터페이스 빌더에서 하나만 선택하는 것입니다. 여러 항목이 설정되지 않은 추가 보안을 NSAssert위해 각각의 setter에를 추가하십시오 .

- (void)setSomeBool:(BOOL)flag
{
    if (flag)
    {
        NSAssert(!_someOtherFlag && !_someThirdFlag, @"Only one flag can be set");
    }
}

이것은 약간 지루하고 약간 엉성한 IMO이지만 제가 생각할 수있는 이런 종류의 행동을 수행하는 유일한 방법입니다.


1

enumObjective-C의 모든 사용자가 런타임에 의 식별자를 사용할 수 없다고 추가하고 싶습니다 . 따라서 어디에도 표시 할 수 없습니다.


1

내 해결책은 다음과 같습니다.

@IBInspectable  
var keyboardType = UIKeyboardType.default.rawValue {
        didSet { 
             textField.keyboardType = UIKeyboardType(rawValue: keyboardType)! 
        }
}

IB 자체에서 keyboardType 필드에 int를 설정해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.