Подтвердить что ты не робот

Как создать IBInspectable типа enum

enum не, созданный атрибутом среды выполнения Interface Builder. В Interface Interface Attributes Inspector не отображается следующее:

enum StatusShape:Int {
    case Rectangle = 0
    case Triangle = 1
    case Circle = 2
}
@IBInspectable var shape:StatusShape = .Rectangle

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

Q: Как я могу увидеть enum в инспекторе атрибутов интерфейса Builder?

4b9b3361

Ответ 1

Swift 3

@IBInspectable var shape:StatusShape = .Rectangle просто создает пустую запись в Interface Builder:

Недоступно в IB

Используйте адаптер, который будет действовать как мост между Swift и Interface Builder.
shapeAdapter проверяется с IB:

   // IB: use the adapter
   @IBInspectable var shapeAdapter:Int {
        get {
            return self.shape.rawValue
        }
        set( shapeIndex) {
            self.shape = StatusShape(rawValue: shapeIndex) ?? .Rectangle
        }
    }

Доступно в IB

В отличие от подхода условной компиляции (с использованием #if TARGET_INTERFACE_BUILDER), тип переменной shape не изменяется с целью, потенциально требуя дальнейших изменений исходного кода, чтобы справиться с вариантами shape:NSInteger vs. shape:StatusShape:

   // Programmatically: use the enum
   var shape:StatusShape = .Rectangle

Полный код

@IBDesignable
class ViewController: UIViewController {

    enum StatusShape:Int {
        case Rectangle
        case Triangle
        case Circle
    }

    // Programmatically: use the enum
    var shape:StatusShape = .Rectangle

    // IB: use the adapter
    @IBInspectable var shapeAdapter:Int {
        get {
            return self.shape.rawValue
        }
        set( shapeIndex) {
            self.shape = StatusShape(rawValue: shapeIndex) ?? .Rectangle
        }
    }
}

► Найдите это решение на GitHub.

Ответ 2

Вместо того, чтобы устанавливать ваши проверенные перечисления с помощью ints, вы также можете установить их со строками. Хотя это и не столь предпочтительнее, как выпадающий список, по крайней мере, этот вариант предлагает некоторую степень удобочитаемости.

Только для Swift:

// 1. Set up your enum
enum Shape: String {
    case Rectangle = "rectangle" // lowercase to make it case-insensitive
    case Triangle = "triangle"
    case Circle = "circle"
}


// 2. Then set up a stored property, which will be for use in code
var shape = Shape.Rectangle // default shape


// 3. And another stored property which will only be accessible in IB (because the "unavailable" attribute prevents its use in code)
@available(*, unavailable, message: "This property is reserved for Interface Builder. Use 'shape' instead.")
@IBInspectable var shapeName: String? {
    willSet {
        // Ensure user enters a valid shape while making it lowercase.
        // Ignore input if not valid.
        if let newShape = Shape(rawValue: newValue?.lowercased() ?? "") {
            shape = newShape
        }
    }
}

Можно также заставить это работать с objective-c, добавив инициализатор к перечислению. Однако компилятор будет показывать только "недоступную" ошибку для ваших свойств только для IB в быстром коде.

Swift Option с совместимостью Obj-C:

@objc enum Shape: Int {
    case None
    case Rectangle
    case Triangle
    case Circle

    init(named shapeName: String) {
        switch shapeName.lowercased() {
        case "rectangle": self = .Rectangle
        case "triangle": self = .Triangle
        case "circle": self = .Circle
        default: self = .None
        }
    }
}

var shape = Shape.Rectangle // default shape

@available(*, unavailable, message: "This property is reserved for Interface Builder. Use 'shape' instead.")
@IBInspectable var shapeName: String? {
    willSet {
        if let newShape = Shape(rawValue: newValue?.lowercased() ?? "") {
            shape = newShape
        }
    }
}

Ответ 3

Я не могу вспомнить быстрый синтаксис, но именно так я решил его в obj-c

#if TARGET_INTERFACE_BUILDER
@property (nonatomic) IBInspectable NSInteger shape;
#else
@property (nonatomic) StatusShape shape;
#endif

Ответ 4

Это старый поток, но полезный. Я адаптировал свой ответ к быстрым 4.0 и Xcode 9.0 - у Swift 4 есть свои небольшие проблемы с этой проблемой. У меня есть переменная @IBInspectable с типом перечисления, а Xcode 9.0 недовольна, показывая мне, что это свойство не может быть помечено как @IBInspectable, потому что его тип не может быть представлен в Objective-c "

@Eporediese частично отвечает на эту проблему (для swift3); используя свойство для раскадровки, но прямое перечисление для остальной части кода. Ниже приведен более полный набор кодов, который дает вам свойство работать в обоих случаях.

enum StatusShape: Int {
  case Rectangle = 0
  case Triangle = 1
  case Circle = 2
}
var _shape:StatusShape = .Rectangle  // this is the backing variable

#if TARGET_INTERFACE_BUILDER
  @IBInspectable var shape: Int {    // using backing variable as a raw int

    get { return _shape.rawValue }
    set {
      if _shape.rawValue != newValue {
        _shape.rawValue = newValue
      }
    }
}
#else
var shape: StatusShape {  // using backing variable as a typed enum
  get { return _shape }
  set {
    if _shape != newValue {
      _shape = newValue
    }
  }
}
#endif

Ответ 5

Вы не можете. Если вы хотите, чтобы он был доступен в Interface Builder, сделайте ваше свойство одним из поддерживаемых типов. В этом случае сделайте его int и примените его к типу перечисления в коде.

Ответ 6

Swift 3 решение на основе SwiftArchitect

enum StatusShape: Int {
    case rectangle, triangle, circle
}
var statusShape: StatusShape = .rectangle
#if TARGET_INTERFACE_BUILDER
@IBInspectable var statusShapeIB: Int {
    get { 
        return statusShape.rawValue 
    }
    set { 
        guard let statusShape = StatusShape(rawValue: newValue) else { return }
        self.statusShape = statusShape
    }
}   //convenience var, enum not inspectable
#endif

Ответ 7

I just removed @IBInspectable keyword 
//MARK:- Not confirm its will work for other or not but easy way once you can try it

откуда появилась эта ошибка (для меня это было дважды). Это потребует от вас разблокировки библиотеки VHBoomMenuButton, чтобы вы могли вносить изменения.

and its work