ios @IBInspectable 与枚举?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28749598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:00:55  来源:igfitidea点击:

@IBInspectable with enum?

iosobjective-ciphonexcodeswift

提问by ignotusverum

I'd like to create @IBInspectableelement as you see at the picture below :

我想创建@IBInspectable如下图所示的元素:

enter image description here

在此处输入图片说明

my idea is to use something like enum as type for @IBInspectable, but it looks like it's not the case, any ideas how to implement element like this ?

我的想法是使用 enum 之类的东西作为 for 的类型@IBInspectable,但看起来情况并非如此,任何想法如何实现这样的元素?

EDIT:

编辑:

It looks like @IBInspectablesupports only these types :

看起来@IBInspectable只支持这些类型:

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

bummer

无赖

回答by yusuke024

That's not possible (for now). You can only use those types that you see in User Defined Runtime Attributessection.

这是不可能的(目前)。您只能使用在用户定义的运行时属性部分中看到的那些类型。

From Apple's doc:

来自苹果的文档

You can attach the IBInspectable attribute to any property in a class declaration, class extension, or category for any type that's supported by the Interface Builder defined runtime attributes: boolean, integer or floating point number, string, localized string, rectangle, point, size, color, range, and nil.

对于 Interface Builder 定义的运行时属性支持的任何类型,您可以将 IBInspectable 属性附加到类声明、类扩展或类别中的任何属性:布尔值、整数或浮点数、字符串、本地化字符串、矩形、点、大小、颜色、范围和零。

回答by Anthony Mattox

Another work-around for this is to alter how an enumeration property appears to interface builder. For example:

另一个解决方法是改变枚举属性在界面构建器中的显示方式。例如:

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

This assumes an enum called FontWeight. It relies on the fact that enums and their raw integer values can be used somewhat interchangeably in Objective-C. After doing this you are able to specify an integer in Interface builder for the property which is not ideal, but works, and retains a small amount of type safety when using the same property programatically.

这假定一个名为 FontWeight 的枚举。它依赖于这样一个事实,即枚举及其原始整数值在 Objective-C 中可以互换使用。执行此操作后,您可以在 Interface builder 中为该属性指定一个整数,该整数并不理想,但有效,并在以编程方式使用相同属性时保留了少量类型安全性。

This is a better alternative than declaring a separate integer property because you don't need to write extra logic to handle a second integer property which could also be used to accomplish the same thing.

这是比声明单独的整数属性更好的替代方法,因为您不需要编写额外的逻辑来处理第二个整数属性,该逻辑也可用于完成相同的事情。

However, this does not work with Swift because we're not able to implicitly cast from an integer to an enum. Any thoughts on solving that would be appreciated.

但是,这不适用于 Swift,因为我们无法从整数隐式转换为枚举。任何解决这个问题的想法将不胜感激。

回答by Matthew Cawley

I do this using a Inspectable NSInteger value and override the setter to allow it to set the enum. This has the limitation of not using a popup list and if you change your enum values, then the interface options will not update to match.

我使用 Inspectable NSInteger 值执行此操作并覆盖 setter 以允许它设置枚举。这具有不使用弹出列表的限制,如果您更改枚举值,则界面选项将不会更新以匹配。

Example.

例子。

In Header File:

在头文件中:

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

...

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

In the implementation file:

在实现文件中:

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

You could optionally add some logic in there to ensure that it is being set to a valid value

您可以选择在其中添加一些逻辑以确保将其设置为有效值

回答by HixField

Sikhapol is correct, enums are not yet supported also not in xCode 9. I believe the safest approach is to use enums as strings and implement a "shadow" (private) IBInspectable var. Here is an example of a BarBtnPaintCode item which represents a barbutton item that can be styled with a custom icon (that is done using PaintCode) right inside Interface Builder (swift 4).

Sikhapol 是正确的,xCode 9 中也不支持枚举。我相信最安全的方法是将枚举用作字符串并实现“影子”(私有)IBInspectable 变量。这是一个 BarBtnPaintCode 项目的示例,它表示可以在 Interface Builder (swift 4) 中使用自定义图标(使用 PaintCode 完成)设置样式的栏按钮项目。

In interface build you just enter the string (identical to the enum value), which keeps it clear (if you are entering numbers nobody knows what they mean)

在界面构建中,您只需输入字符串(与枚举值相同),它会保持清晰(如果您输入数字,则没人知道它们的含义)

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
        }

    }

}

回答by Gal Marom

My solution was to do :

我的解决办法是:

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

On the IB itself, you will need to set an int in the keyboardType field

在 IB 本身上,您需要在 keyboardType 字段中设置一个 int

回答by Chris

As @sikhapol answered, this is not possible. The workaround I use for this is to have a bunch of IBInspectablebools in my class and just select one in interface builder. For added security that multiple ones are not set, add an NSAssertin the setter for each one.

正如@sikhapol 回答的那样,这是不可能的。我为此使用的解决方法是IBInspectable在我的班级中有一堆布尔值,然后在界面构建器中选择一个。为了增加未设置多个的安全性,请NSAssert在设置器中为每个添加一个。

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

This is a little tedious and a bit sloppy IMO, but it's the only way to accomplish this kind of behavior that I can think of

这有点乏味,有点草率 IMO,但这是我能想到的完成这种行为的唯一方法

回答by Amin Negm-Awad

I want to add that the identifiers of an enumare not available at runtime for anybody in Objective-C. So there cannot be a possibility to display it anywhere.

我想补充一点enum,Objective-C 中的任何人都无法在运行时使用an 的标识符。所以不可能在任何地方显示它。