Класс IBDesignable не работает должным образом

Я создаю новое приложение для iOS с быстрым и пытаюсь создать собственный класс IBDesignable UIButton для использования в дизайнере. Мой код не работает ни в конструкторе, ни в самом приложении во время выполнения. Значение по умолчанию, которое я дал переменным IBInspectable, к ним не относится.

@IBDesignable class MyButton: UIButton {

@IBInspectable var backColor: UIColor = UIColor.red {
    didSet {
        self.backgroundColor = backColor
    }
}

@IBInspectable var textColor: UIColor = UIColor.white {
    didSet {
        self.setTitleColor(textColor, for: .normal)
    }
}

override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setup()
}

override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    setup()
}

private func setup() {
    titleLabel?.font = UIFont.systemFont(ofSize: 17)
    contentEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
    layer.cornerRadius = (frame.height / 2)
    setTitle(title(for: .normal)?.uppercased(), for: .normal)
}
}

Я ожидаю увидеть кнопку в дизайнере/приложении с красным фоном и белым текстом, и ничего из этого не происходит. Я использую Swift 4.2 и Xcode 10.1.


person Eitana Aviv    schedule 20.01.2019    source источник


Ответы (3)


добавить эти две функции

  override func awakeFromNib() {
        super.awakeFromNib()
        self.setup()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        self.setup()
    }

нет необходимости в инициализации

person teodik abrami    schedule 20.01.2019
comment
Спасибо, но это не помогло. - person Eitana Aviv; 20.01.2019

Установка значения свойства по умолчанию не вызывает предложение didSet.
Вам нужно что-то вроде:

    private func setup() {
        titleLabel?.font = UIFont.systemFont(ofSize: 17)
        contentEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
        layer.cornerRadius = (frame.height / 2)
        setTitle(title(for: .normal)?.uppercased(), for: .normal)
        // I would do it differently, but this is just for demo purposes
        // Also, can't assign a prop to itself, so using a temp
        var tmp = self.backColor
        self.backColor = tmp
        tmp = self.textColor
        self.textColor = tmp
    }

Кроме того, Xcode не очень хорошо работает с IBDesignable, в быстром или объективном C.

Убедитесь, что пункт меню: Редактор -> Автоматически обновлять представления отмечен флажком.
Вы также можете явным образом выполнить Редактор -> Обновить все представления.
Из моего опыта - это перестает работать через некоторое время, и вам нужно выйти из Xcode и перезапустить его, чтобы он снова заработал.

person Moshe Gottlieb    schedule 20.01.2019
comment
Это ничего не сделало .. у вас есть хороший и полный пример, который я мог бы использовать? - person Eitana Aviv; 20.01.2019
comment
@EitanaAviv Как я уже сказал, Xcode не очень хорошо работает с IBDesignable. Попробуйте убедиться, что указанный пункт меню отмечен, и закройте Xcode и перезапустите. Я попробовал это с образцом проекта, и это сработало (после перезапуска Xcode). - person Moshe Gottlieb; 20.01.2019
comment
@MosheGottlieb Спасибо, что спасли мой день!! - person luckyShubhra; 07.05.2021

  1. Убедитесь, что ваша кнопка настроена на тип .custom в вашем интерфейсном конструкторе. Это не очевидно, но тип кнопки по умолчанию — .system, который нельзя настроить. Я видел, что у людей не было проблем с этим, но в моих приложениях это всегда было проблемой.

  2. Другая проблема заключается в том, что если вы оставите свои проверяемые значения пустыми, didSet не будет вызываться, и значение по умолчанию не будет применено.

    @IBInspectable var backColor: UIColor? = UIColor.red {
       didSet {
          updateBackground()
      }
    }
    
    private func updateBackground() {
       self.backgroundColor = backColor
    }
    
    func setup() {
       ...
       updateBackground()
    }
    
person Sulthan    schedule 20.01.2019