我想创建类似下图中所示的@IBInspectable
元素:
我的想法是将枚举作为@IBInspectable
的类型,但似乎行不通,有什么实现此类元素的方法吗?
编辑:
看起来@IBInspectable
只支持以下这些类型:
Int
CGFloat
Double
String
Bool
CGPoint
CGSize
CGRect
UIColor
UIImage
遗憾。
我想创建类似下图中所示的@IBInspectable
元素:
我的想法是将枚举作为@IBInspectable
的类型,但似乎行不通,有什么实现此类元素的方法吗?
编辑:
看起来@IBInspectable
只支持以下这些类型:
Int
CGFloat
Double
String
Bool
CGPoint
CGSize
CGRect
UIColor
UIImage
遗憾。
目前不可能做到这一点。您只能使用在 用户自定义运行时属性 部分中看到的这些类型。
根据苹果公司的 文档:
您可以将 IBInspectable 属性附加到类声明、类扩展或类别中的任何属性上,针对接口构建器定义的运行时属性支持的任何类型:布尔值、整数或浮点数、字符串、本地化字符串、矩形、点、大小、颜色、范围和 nil。
另一个应对方法是更改枚举属性在界面构建器中的显示方式。例如:
#if TARGET_INTERFACE_BUILDER
@property (nonatomic, assign) IBInspectable NSInteger fontWeight;
#else
@property (nonatomic, assign) FontWeight fontWeight;
#endif
假设有一个名为“FontWeight”的枚举,此方法依赖于 Objective-C 中的枚举及其原始整数值可以在某种程度上互换使用的事实。完成此操作后,您可以在界面生成器中为属性指定整数,尽管这不是理想的,但它仍然有效,并在以编程方式使用相同属性时保留了一小部分类型安全性。
与声明单独的整数属性相比,这是更好的选择,因为您不需要编写额外的逻辑来处理第二个整数属性,该属性也可以用于完成相同的事情。
但是,在Swift中,这种方法无法工作,因为我们无法将整数隐式转换为枚举类型。如果有任何解决方法,请告知。
我使用一个可检查的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;
}
你可以选择在其中添加一些逻辑,以确保它被设置为有效值。
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
}
}
}
@IBInspectable
var keyboardType = UIKeyboardType.default.rawValue {
didSet {
textField.keyboardType = UIKeyboardType(rawValue: keyboardType)!
}
}
我想补充一点,在Objective-C中,enum
的标识符对于任何人在运行时都不可用。因此无法在任何地方显示它。
IBInspectable
布尔值来解决这个问题,在接口构建器中只需选择其中一个即可。为了确保没有设置多个,可以在每个属性的setter中添加NSAssert
。- (void)setSomeBool:(BOOL)flag
{
if (flag)
{
NSAssert(!_someOtherFlag && !_someThirdFlag, @"Only one flag can be set");
}
}