Если я вас правильно понял, вы в основном хотите указать имя объекта в Interface Builder, да? т.е. вы хотите иметь возможность в основном выбирать свой пользовательский класс из инспектора?
Если это так, то это, к сожалению, невозможно напрямую. @IBInspectable можно использовать только с определенными типами, как задокументировано здесь:
Вы можете добавить атрибут IBInspectable к любому свойству в объявлении класса, расширении класса или категории типа: логическое значение, целое число или число с плавающей запятой, строка, локализованная строка, прямоугольник, точка, размер, цвет, диапазон и ноль.
Однако вы можете указать строковое свойство как IBInspectable (с значимым значением по умолчанию), и в ваших инициализаторах вычесть из него класс. Это оставит открытой возможность ошибки, то есть опечатки, но все же может работать.
См. также этот ответ.
Редактировать после вашего комментария: В этом случае я боюсь, что это будет невозможно (по крайней мере, насколько я знаю, может быть какой-то хакерский прием глубокого уровня, о котором я не знаю, но это скорее всего будет некрасиво). Проблема в том, что то, что указано в IB, может быть оценено только во время выполнения, а typealias определяется во время компиляции.
Я думаю, что в основном вам нужен просто протокол для функций, которые должен иметь каждый класс ячеек (и на который опирается общий контроллер представления). Тогда вам даже не понадобится typealias, поскольку протокол сам по себе является типом.
Затем можно выбрать конкретные классы ячеек на основе строки IBInspectable
, протокол может даже определить для этого метод.
В зависимости от деталей вашего сценария вы можете даже написать общий суперкласс для всех ячеек. Тот, который уже принимает (часть) протокола (в этом случае вы можете даже не использовать протокол, но я бы рекомендовал использовать его для удобочитаемости).
Это, очевидно, предполагает, что у вас есть все необходимые функции для контроллера представления, определенного для ваших общих ячеек, но это проблема, с которой вы сталкиваетесь в любом случае (даже если вы можете использовать псевдоним типа, определенный во время выполнения).
Второе редактирование после просмотра вашего примера кода:
Хорошо, я посмотрел на это еще раз и, надеюсь, теперь могу объяснить это немного лучше. К сожалению, я не могу просто добавить в ваш репозиторий напрямую, так как он не компилируется (мне не хватает фреймворка/модуля Realm, и даже если бы я добавил, что, вероятно, ничего не выиграл бы, потому что я не знаю, что именно вы с ним делаете ).
Как сказано в комментарии, я бы сказал, что вам не нужно дополнительное свойство IBInspectable для установки класса. Это уже должно произойти в вашей раскадровке, т. е. вы должны установить значение класса данной ячейки-прототипа на один из конкретных классов ячеек, которые у вас есть. Однако вашему универсальному RealmTableViewController
не нужно знать этот класс. Вы, кажется, хотите дать ему знание о том, что, если я правильно вас понимаю, вероятно, чтобы он правильно подготовил ячейку в зависимости от ее конкретных характеристик. Не делайте этого (сейчас я перейду к тому, что вы хотите сделать в viewDidLoad
). Вместо этого определить протокол, который принимают все ячейки и о котором знает RealmTableViewController
. В вашем методе tableView(_:cellForRowAt:)
вы используете этот протокол в части as! ...
при удалении ячейки из очереди. Протокол должен определять метод подготовки, который должен быть реализован каждым конкретным классом и который затем вызывается в этот момент RealmTableViewController
.
Таким образом, ваш контроллер табличного представления остается универсальным, он ничего не знает о отображаемых ячейках, как и предполагалось.
Теперь к проблеме, с которой вы (я думаю) сталкиваетесь: вы хотите, чтобы контроллер знал, какой тип ячейки-прототипа он использует, чтобы он тоже мог подготовить определенные вещи (которые вы также можете передать в протокол, например). Это проблематично, потому что вы в основном пытаетесь восстановить основной аспект контроллера табличного представления: способность обрабатывать разные типы ячеек одновременно. Я заключаю это из вашего другого кода, в viewDidLoad
и свойстве objects
, которое в конечном итоге, похоже, также зависит от класса ячейки. Это противоречит дизайну самой табличной архитектуры, это не просто синтаксическая проблема. Однако есть решение: другой протокол плюс класс-компаньон для конкретных классов ячеек.
Для каждого класса ячеек, который у вас есть, определите соответствующий класс, который имеет дело с вещами Realm, которые должны выполнять ваши контроллеры представления. Может быть, для некоторых ячеек у вас есть один и тот же объект, тогда напишите их соответствующим образом (у нового класса должно быть свойство, определяющее, какой ячейке он соответствует). Определите протокол, который они все принимают и который имеет по крайней мере два метода (можно использовать лучшие имена, здесь уже поздно...): doControllerStuff
и getCellIdentifier
.
Тогда ваш RealmTableViewController
, наконец, действительно получает IBInspectable. Если это установлено, контроллер создает объект-компаньон в ячейке (какой конкретный класс используется, очевидно, будет зависеть от значения IBInspectable). Если один и тот же компаньон обрабатывает несколько ячеек, IBInspectable также должен определить, какая ячейка будет использоваться, т. е. компаньон должен быть настроен правильно. Вы можете использовать какое-то строковое соглашение или даже написать фабричный класс, который скрывает конкретный класс от контроллера представления и просто возвращает ему правильный объект, типизированный как протокол.
В любом случае, что бы вы ни делали в viewDidLoad
на основе класса, измените это на метод doControllerStuff
. У вас может быть даже несколько супер- и подклассов, если это может быть общим для ячеек/компаньонов, это не имеет значения. Наконец, в вашем методе `tableView(_:cellForRowAt:) вы не используете идентификатор напрямую, а вместо этого запрашиваете идентификатор у объекта-компаньона.
Однако здесь есть небольшое предостережение: вы, очевидно, должны убедиться, что значение построителя интерфейса для идентификатора ячейки установлено правильно, то есть оно соответствует IBInspectable, который вы установили в экземпляре контроллера представления. Вы можете написать об этом ловушку и использовать ячейку по умолчанию, или просто выдать исключение.
Это стало довольно длинным, и я надеюсь, что это понятно, несмотря на это. У меня нет времени, чтобы сделать красивую графику или что-то в этом роде, поэтому, если у вас все еще есть вопросы, я предлагаю обсудить это в чате. :) Просто пингуйте меня, и мы это сделаем (хотя у меня немного свободного времени, начиная с завтрашнего дня).
person
Gero
schedule
15.05.2017
RealmTableViewController
, поэтому я вынужден повторить свой код, заменив псевдоним типа. Я хотел бы иметь общий класс, который можно определить в InterfaceBuilder, набрав в @IBInspectable EntityName - person pesch   schedule 11.05.2017