@IBInspectable with an enumeration?

I would like to create an @IBInspectable element, as you see in the image below:

enter image description here

My idea is to use something like enum as type for @IBInspectable , but it looks like it is not, any ideas how to implement such an element?

EDIT:

It seems that @IBInspectable only supports these types:

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

bummer

+64
ios objective-c iphone xcode swift
Feb 26 '15 at 18:02
source share
6 answers

This is not possible (at the moment). You can only use the types that you see in the "User Defined Runtime Attributes" section.

From Apple doc :

You can attach the IBInspectable attribute to any property in the class declaration, class extension, or category for any type supported by the specified attributes of the Builder Interface runtime: boolean, integer or floating point number, line, localized line, rectangle, dot, size, color, range and zero.

+22
Feb 26 '15 at 18:09
source share

Another problem for this is changing the way the enumeration property is displayed in the interface builder. For example:

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

This involves an enumeration called FontWeight. He relies on the fact that enumerations and their raw integer values ​​can be used somewhat interchangeably in Objective-C. After that, you can specify an integer in the interface builder for a property that is not ideal, but works and retains a small degree of security when using the same property programmatically.

This is a better alternative than declaring a single integer property, because you do not need to write additional logic to handle the second integer property, which can also be used to achieve the same.

However, this does not work with Swift, because we cannot implicitly cast from an integer in enum. Any thoughts on resolving this will be appreciated.

+17
Oct 22 '15 at 2:07
source share

I do this using the Inspectable NSInteger value and override the setter so that it can set the enumeration. This limits the use of the popup list, and if you change the enumeration values, the interface parameters will not be updated to match.

Example.

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

Perhaps you can add some logic there to make sure that it is set to a valid value.

+6
May 28 '15 at 1:19
source share

As @sikhapol replied, this is not possible. The workaround I use for this is to have a bunch of IBInspectable bools in my class and just select it in the interface builder. For added security that is not installed, add NSAssert to the setter for each of them.

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

This is a bit tedious and a bit messy IMO, but it's the only way I can think of behavior that I can think of

+1
Feb 26 '15 at 18:17
source share

I want to add that enum identifiers are not available at runtime for any user in Objective-C. Therefore, it may not be possible to display it anywhere.

+1
Feb 26 '15 at 19:59
source share

My decision was to make:

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

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

0
Jun 22 '17 at 8:44
source share



All Articles