[ios] @IBInspectable with enum?

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

여기에 이미지 설명 입력

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

편집하다:

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

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

부끄러워



답변

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

Apple의 문서에서 :

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


답변

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

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

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

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

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


답변

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

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


답변

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
        }

    }

}


답변

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

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

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


답변

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


답변

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

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

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