@IBInspectable с перечислением?

Я хотел бы создать элемент @IBInspectable, как вы видите на рисунке ниже:

enter image description here

Моя идея - использовать что-то вроде enum как type для @IBInspectable, но похоже, что это не так, любые идеи, как реализовать такой элемент?

EDIT:

Похоже, что @IBInspectable поддерживает только эти типы:

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

облом

Ответ 1

Это невозможно (на данный момент). Вы можете использовать только те типы, которые вы видите в разделе "Определенные пользователем атрибуты времени выполнения".

От Apple doc:

Вы можете прикрепить атрибут IBInspectable к любому свойству в объявлении класса, расширении класса или категории для любого типа, поддерживаемого указанными атрибутами среды выполнения Builder Interface: boolean, integer или число с плавающей точкой, строка, локализованная строка, прямоугольник, точку, размер, цвет, диапазон и ноль.

Ответ 2

Еще одна проблема для этого - изменить способ отображения свойства перечисления в построителе интерфейса. Например:

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

Это предполагает перечисление, называемое FontWeight. Он полагается на то, что перечисления и их необработанные целые значения могут использоваться несколько взаимозаменяемо в Objective-C. После этого вы можете указать целое число в построителе интерфейса для свойства, которое не является идеальным, но работает и сохраняет небольшую степень безопасности при использовании того же свойства программно.

Это лучшая альтернатива, чем объявление отдельного целочисленного свойства, потому что вам не нужно писать дополнительную логику для обработки второго целочисленного свойства, которое также может быть использовано для достижения того же самого.

Однако это не работает с Swift, потому что мы не можем неявно отбрасывать из целого числа в enum. Любые мысли о решении этого будут оценены.

Ответ 3

Я делаю это с использованием значения 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;
}

Возможно, вы можете добавить туда некоторую логику, чтобы убедиться, что она установлена ​​на допустимое значение

Ответ 4

Как ответил @sikhapol, это невозможно. Обходной путь, который я использую для этого, состоит в том, чтобы иметь кучу IBInspectable bools в моем классе и просто выбрать его в построителе интерфейса. Для дополнительной безопасности, которая не установлена, добавьте NSAssert в сеттер для каждого из них.

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

Это немного утомительная и немного неряшливая ИМО, но это единственный способ добиться такого поведения, о котором я могу думать о

Ответ 5

Я хочу добавить, что идентификаторы enum недоступны во время выполнения для любого пользователя в Objective-C. Таким образом, не может быть возможности отобразить его в любом месте.

Ответ 6

Мое решение должно было сделать:

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

В самой IB вам нужно будет установить int в поле keyboardType