2015-02-26 4 views
67

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

enter image description here

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

EDIT:

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

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

облом

+0

обходной путь, своего рода, чтобы положить осматриваемом вычисленное свойство в перед значением, которое вы хотите установить. Конечно, он по-прежнему не будет волшебным образом появляться как всплывающее меню перечисляемых значений в Interface Builder; но по крайней мере вы можете определить контролируемое значение и использовать его для установки перечисления. – matt

+4

На WWDC в этом году я спросил инженера Apple в лаборатории Developer Tools об этом. Он сказал, что согласен, что это будет отличная функция, но в настоящее время это невозможно. Он предложил мне подать радар на https://bugreport.apple.com, который я сделал. Он был закрыт как дубликат номера 15505220, но я бы очень рекомендовал людям, занимающимся подобными вопросами. Эти вещи часто решаются, если достаточно людей жалуются. –

+1

как этот вопрос отличается от http://stackoverflow.com/questions/27432736/how-to-create-an-ibinspectable-of-type-enum – SwiftArchitect

ответ

23

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

От doc Apple:

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

+1

Когда я хочу использовать перечисление, я даю значения перечисления явным назначениям (= 1, = 2, и т.д.). И в обработчике я добавляю утверждение, если значение из IB не является одним из значений из перечисления. Раздражает то, что перечисления не поддерживаются, но этот трюк делает их более полезными, по крайней мере. –

+0

Перечисление представляет собой целое число. –

+0

Все еще невозможно в Xcode 6.3.1 использовать типы перечислений ... – matm

1

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

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

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

1

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

6

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

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

+0

Не знаете, почему это было проголосовано. Кажется, это хороший способ обойти эту проблему. – Fogmeister

+0

Спасибо @Fogmeister - на самом деле я использую эту реализацию внутри приложения :) –

18

Другая работа для этого - изменить, как свойство перечисления появляется в построителе интерфейса. Например:

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

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

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

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

+1

Я действительно думал, что это работает в Swift, но в дальнейшем тестировании ... нет –

0

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

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

На самом IB, вам нужно будет установить Int в поле keyboardType

Смежные вопросы