Я хочу создать @IBInspectable
элемент, как вы видите на картинке ниже:
Моя идея состоит в том, чтобы использовать что-то вроде перечисления в качестве типа @IBInspectable
, но похоже, что это не так, есть идеи, как реализовать такой элемент?
РЕДАКТИРОВАТЬ:
Похоже, @IBInspectable
поддерживает только эти типы:
Int
CGFloat
Double
String
Bool
CGPoint
CGSize
CGRect
UIColor
UIImage
облом
Ответы:
Это невозможно (пока). Вы можете использовать только те типы, которые вы видите в разделе « Пользовательские атрибуты времени выполнения ».
От компании Apple документа :
источник
Другой способ решения этой проблемы - изменить способ отображения свойства перечисления для построителя интерфейса. Например:
#if TARGET_INTERFACE_BUILDER @property (nonatomic, assign) IBInspectable NSInteger fontWeight; #else @property (nonatomic, assign) FontWeight fontWeight; #endif
Это предполагает наличие перечисления FontWeight. Он основан на том факте, что перечисления и их необработанные целочисленные значения могут использоваться в Objective-C как синонимы. После этого вы можете указать целое число в построителе интерфейса для свойства, которое не идеально, но работает и сохраняет небольшую степень безопасности типов при программном использовании того же свойства.
Это лучшая альтернатива, чем объявление отдельного целочисленного свойства, поскольку вам не нужно писать дополнительную логику для обработки второго целочисленного свойства, которое также можно использовать для достижения того же результата.
Однако это не работает со Swift, потому что мы не можем неявно приводить целое число к перечислению. Любые мысли о решении, которые будут оценены.
источник
Я делаю это, используя значение 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; }
При желании вы можете добавить туда некоторую логику, чтобы гарантировать, что для него установлено допустимое значение
источник
Sikhapol верен, перечисления еще не поддерживаются, также не поддерживаются в xCode 9. Я считаю, что самый безопасный подход - использовать перечисления как строки и реализовать «теневую» (частную) IBInspectable var. Вот пример элемента BarBtnPaintCode, который представляет собой элемент barbutton, который можно стилизовать с помощью настраиваемого значка (что делается с помощью PaintCode) прямо внутри Interface Builder (swift 4).
В сборке интерфейса вы просто вводите строку (идентичную значению перечисления), которая сохраняет ее ясной (если вы вводите числа, никто не знает, что они означают)
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 } } }
источник
Как ответил @sikhapol, это невозможно. Обходной путь, который я использую для этого, - иметь кучу
IBInspectable
bools в моем классе и просто выбрать один в построителе интерфейса. Для дополнительной безопасности, что несколько единиц не установлены, добавьтеNSAssert
в сеттер для каждого из них.- (void)setSomeBool:(BOOL)flag { if (flag) { NSAssert(!_someOtherFlag && !_someThirdFlag, @"Only one flag can be set"); } }
Это немного утомительно и немного небрежно ИМО, но это единственный способ добиться такого поведения, о котором я могу думать.
источник
Я хочу добавить, что идентификаторы объекта
enum
недоступны во время выполнения для кого-либо в Objective-C. Так что не может быть возможности его где-либо отобразить.источник
Мое решение было сделать:
@IBInspectable var keyboardType = UIKeyboardType.default.rawValue { didSet { textField.keyboardType = UIKeyboardType(rawValue: keyboardType)! } }
На самом IB вам нужно будет установить int в поле keyboardType
источник