Swift: как реализовать пользовательские атрибуты времени выполнения

Итак, я реализую настраиваемую панель инструментов "chooser", такую ​​как iOS-эквивалент набора радиокнопок (UISegmentedControl). Просто горизонтальная панель, разделенная на опции.

Для этого я создал подкласс UIControl под названием SegmentedControl и реализовал пользовательский чертеж. Однако, с таким представлением, мне нужно установить, какие доступны доступные параметры. Я мог бы просто получить доступ к представлению с контроллера viewDidLoad() и установить их там, но мне нравится использовать конструктор интерфейса для такого рода материалов.

Итак, я обнаружил эту замечательную вещь под названием "Пользовательские атрибуты времени выполнения". Я создал атрибут String с ключом buttonValues и установил значение (это простой Мужской/Женский выбор, поэтому я пошел с "Male | Female" ). Я узнал, что вы можете получить доступ к этим значениям с помощью функции self.valueForKey() и передать ключ. Я сделал парсер, чтобы превратить эту строку в массив, а затем добавил функциональность для функции drawRect(), чтобы использовать массив для настройки кнопок.

Когда я запустил приложение, я получил сообщение об ошибке "Кодирование соответствия ключевых значений".

Итак, я посмотрел на это, и я узнал, что класс должен иметь резервные переменные для хранения атрибутов. Так хорошо, я добавил переменную экземпляра под названием buttonValues и инициализировал ее до "". Теперь приложение работает нормально, но значение выходит из функции self.valueForKey(). Я просмотрел учебники о том, как настроить пользовательские атрибуты времени выполнения, но они недостаточно подробно описаны. Они говорят о соблюдении ключевых правил кодирования, как о том, что я должен просто знать.

Я хотел бы точно знать, что я должен сделать, чтобы это правильно работало, подробно.

Ответы

Ответ 1

В ваших целях вы можете использовать либо определенные пользователем атрибуты времени выполнения, либо раскрывать свой класс и свойства как редактируемые в Interface Builder. В любом случае, вы захотите объявить свои свойства как неявно развернутые. Необязательные переменные - IBOutlets создаются одинаково. Если вам нужно внести другие изменения после того, как ваши свойства имеют значение, дайте им didSet наблюдателям свойств. Во время инициализации свойства будут иметь значение по умолчанию (или nil, если не было установлено по умолчанию) и установить, когда представление добавлено в супервизор.

Пользовательские атрибуты времени выполнения

Это работает более или менее, как описано выше - вот простейшая версия:

class LabeledView : UIView {
    var viewLabel: String! {
    didSet {
        println("didSet viewLabel, viewLabel = \(self.viewLabel)")
    }
    }

    init(coder aDecoder: NSCoder!)  {
        super.init(coder: aDecoder)
        println("init with coder, viewLabel = \(self.viewLabel)")
    }
}

Затем установите для атрибута viewLabel значение "Hello" в представлении в вашем раскадровке, например:

Xcode panel showing user-defined runtime attributes

Когда вы создаете и запускаете, консоль покажет, что свойство задано правильно:

init with coder, viewLabel = nil
didSet viewLabel, viewLabel = Hello

@IBDesignable и @IBInspectable

Это дает вашему пользовательскому представлению гораздо более удобный интерфейс в IB - установите атрибут @IBDesignable в свой класс и атрибуты @IBInspectable для каждого свойства. Здесь тот же класс:

@IBDesignable class LabeledView : UIView {
    @IBInspectable var viewLabel: String!

    init(coder aDecoder: NSCoder!)  {
        super.init(coder: aDecoder)
    }
}

Теперь вы можете установить свои проверяемые свойства в верхней части Инспектора атрибутов в построителе интерфейсов:

Attributes Inspector with inspectable property