@IBInspectable与枚举?


86

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

在此处输入图片说明

我的想法是使用像enum这样的类型作为类型@IBInspectable,但是看起来并非如此,有什么想法如何实现这样的元素?

编辑:

看起来@IBInspectable仅支持以下类型:

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

笨蛋


一种解决方法是将可检查的计算属性放在要设置的值前面。当然,它仍然不会神奇地出现在Interface Builder中作为枚举值的弹出菜单。但是至少您可以定义一个可检查的值并使用它来设置一个枚举。
马特2015年

8
在今年的WWDC上,我问了开发人员工具实验室的一位Apple工程师。他说,他同意这将是一个很棒的功能,但目前尚不可能。他建议我在bugreport.apple.com上提交雷达报告。它已作为问题15505220的副本关闭,但我强烈建议人们提出类似的问题。如果足够多的人抱怨,这些事情通常会得到解决。
克拉克



借助SwiftUI和Xcode 11中的新Canvas,看来这永远不会出现在苹果的路线图上
Ben Leggiero

Answers:


26

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

从苹果的文档

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


2
当我想使用一个枚举时,我给枚举值明确的赋值(= 1 = 2,依此类推)。在处理程序中,如果IB中的值不是枚举中的值之一,则添加一个断言。令人讨厌的是,不支持枚举,但是这种技巧至少使它们更有用。
Zev Eisenberg

枚举是整数。
Amin Negm-Awad 2015年

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值执行此操作,并覆盖设置程序以允许它设置枚举。这具有不使用弹出列表的限制,并且如果您更改枚举值,则界面选项将不会更新以匹配。

例。

在头文件中:

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 2015年

谢谢@Fogmeister-目前我实际上正在应用程序内使用此实现:)
Matthew Cawley 2015年

4

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

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

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可以毫无问题地实现。如果您使用此方法,请注意在情节提要和xib中正确拼写类型
MindBlower3

1

正如@sikhapol回答的那样,这是不可能的。我为此使用的解决方法是IBInspectable在我的课程中添加一堆布尔变量,然后在界面生成器中选择一个。为了增加安全性,不要设置多个,请NSAssert在设置器中为每个设置一个。

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

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


1

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


1

我的解决方案是:

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

在IB本身上,您将需要在keyboardType字段中设置一个整数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.