2017-02-19 2 views
2

Я пытаюсь добавить цвет IBInspectable в UIView, чтобы я мог установить его в раскадровке, а затем использовать его в коде. В this post regarding UITextField Я видел, что я могу использовать расширения и добавлять вычисленное свойство, но я не могу заставить его работать для UIView.Невозможно установить @IBInspectable вычисляемое свойство в UIView

Identity inspector enter image description here

я получаю аварию: Не удались установить (additionalColor1) определенный пользователь досматриваемой собственность на (UIView): [SetValue: forUndefinedKey]: этот класс не является значением ключа кодирования совместимым для ключ дополнительныйColor1.

Любая идея, что вызывает крушение и как его исправить?

Вот мой код:

extension UIView { 
    @IBInspectable var additionalColor1: UIColor? { 
     return self.additionalColor1 
    } 
} 

Для справки, я вставить код, который может быть использован для установки цвета заполнителя для UITextField (так же, как и выше URL). Это работает нормально:

extension UITextField { 
    @IBInspectable var placeHolderColor: UIColor? { 
     get { 
      return self.placeHolderColor 
     } 
     set { 
      self.attributedPlaceholder = NSAttributedString(string: self.placeholder != nil ? self.placeholder! : "", attributes:[NSForegroundColorAttributeName: newValue!]) 
     } 
    } 
} 
+0

Как установить * self.additionalColor1 *? Если он находится в коде, как его может выполнить инструмент времени разработки? – dfd

+0

Afaik 'self.additionalColor1' должен быть установлен в раскадровке. Я вставил изображение, показывающее, что я установил его в инспекторе идентификации. В моем скрининге я не обманул сеттера. Однако добавление 'self.additionalColor1 = newValue' в сеттер все равно приводит к сбою. – Andrej

+1

Я смущен. Мой первоначальный комментарий (быстро удаленный) также спросил, можно ли разместить IBInspectable в расширении. Затем я заметил, что вы утверждаете, что можете (placeHolderColor). Так что, предположив, что это возможно, почему вы кодируете дополнительныйColor1 по-другому? У вас есть явный getter/setter в одном, но не в другом. И (я думаю), если вы удалите концепцию IBInspectable для дополнительногоColor1, вы закодировали свойство только для чтения. – dfd

ответ

3

Как уже упоминалось в заголовке вопрос

Swift расширения могут добавлять только вычисленных свойства типа, но они не могут добавлять сохраненные свойства.

(Для получения более подробной информации, пожалуйста, обратитесь к главе Extension в The Swift Programming Language.)

Пример вы вывесили на самом деле недостатки - даже если он имеет 50 upvotes на Stackoverflow в это время. Если вы возвращаете значение самого свойства из getter свойства, вы создаете цикл.

@IBInspectable var additionalColor1: UIColor? { 
    return self.additionalColor1 
} 

Если у вас есть view и вы пытаетесь получить доступ к view.additionalColor1 в любом месте вашего кода поглотителя вашего имущества будет называться возвращающим self.additionalColor1 - или другими словами: он снова возвращает значение свойства - и угадайте как? Позвони себе в геттер! (И так далее ...)

Пример из поста, который вы упоминали только «работает», потому что геттер, очевидно, никогда не звонил. Это только устанавливает, что вычисляемое свойство placeHolderColor, которое изменяет другое сохраненное свойство, а именно текстовое поле attributedPlaceholder.

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

+1

Мы должны сфокусировать или отредактировать связанный неверный рекурсивный ответ. –

1

Как ваш additionalColor будет использоваться?

Я должен был сделать что-то подобное этому недавно, но в моем случае я всегда применял дополнительную ценность сразу.

Например, я хотел создать кнопку, похожую на параллелограмм. Итак, мне нужен способ вставить значение в раскадровку, которая применила бы CGAffineTransform. Я на самом деле не сохраняю значение перекоса, просто использую, чтобы изменить то, что выглядит на самом деле. Затем, в get, я возвращаю значение из подпрограммы вида affineTransform.

@IBInspectable var skewOffset: Float { 
    set(newSkewOffset) { 
     let affineTransform : CGAffineTransform = CGAffineTransform(a: 1.0, b: 0.0, c: CGFloat(newSkewOffset), d: 1.0, tx: 0.0, ty: 0.0) 
     layer.setAffineTransform(affineTransform) 
    } 
    get { 
     return Float(layer.affineTransform().c) 
    } 
} 

Итак, я не хранить skewOffset, я применяю его, и я знаю, как я могу посмотреть его позже, если мне нужно, чтобы получить его.

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