Редактировать: Пожалуйста, смотрите комментарий Даниэля Ханли. Категории могут быть применены выборочно, используя #import
. Приношу свои извинения всем, кто мог быть введен в заблуждение этим ответом. Соответствующие разделы будут отредактированы для дальнейшего использования.
Хорошо, попытка номер два. Насколько мне известно, не существует другого документированного способа реализации требуемой функциональности без подкласса UITableViewCell. Стоит отметить, что документы Apple по UITableViewCell специально упоминают, что методы перехода состояний предназначены для реализации подклассы. При этом, если вам абсолютно необходимо реализовать их без подкласса, есть пара менее традиционных решений. У каждого есть свои проблемы, и может оказаться, что вы не сможете их реализовать, но, тем не менее, это интересный вопрос.
Ответственность
Если вам нужно только вменяемое и относительно простое объяснение, тогда ответьте на ваш вопрос следующим образом: «Нет, способа сделать то, что вы хотите, нет». Я представляю варианты ниже только с утверждение, что они будут работать. Я никоим образом не одобряю их использование. Считай это моим покаянием за то, что я дал мой первый ответ с таким очевидным недостатком.
Вариант первый - Категории
Можно получить требуемую функциональность, переопределив методы, перечисленные в пользовательской категории UITableViewCell.
Проблема в том, что такой подход был бы довольно плохой идеей в 99% случаев. После определения категории в UITableViewCell эти методы будут определены для всех объектов UITableViewCell во всем приложении. Если вам не нужны одинаковые функции перехода между состояниями для каждой ячейки таблицы в приложении, этот подход не очень полезен.
Вариант второй - магия во время выполнения
Вы можете использовать низкоуровневые функции времени выполнения Objective C, чтобы изменить реализацию любого метода на лету. В отличие от опции категорий, этот подход достаточно гибок, чтобы переопределять предполагаемое поведение в любое время, вместо того, чтобы заключать сделку в один прием.
Например, если вы пытаетесь управлять переходами состояний из UITableViewController, вы можете сделать это:
CustomTableViewController.m
#import <objc/runtime.h>
- (void) customStateWillChange:(UITableViewCellStateMask)state
{
//custom UITableViewCell code
}
- (void) viewDidAppear:(BOOL)animated
{
//Store the original implementation
Method originalStateWillChangeMethod = class_getInstanceMethod([UITableViewCell class], @selector(willTransitionToState:));
originalStateWillChangeImplementation = method_getImplementation(originalStateWillChangeMethod); //variable declared in header file as type IMP
//Get the new implementation
Method newStateWillChangeMethod = class_getInstanceMethod([self class], @selector(customStateWillChange:));
IMP newStateWillChangeImplementation = method_getImplementation(newStateWillChangeMethod);
//Replace implementation
method_setImplementation(originalStateWillChangeMethod, newStateWillChangeImplementation);
//the rest of your viewDidAppear code
[super viewDidAppear:animated];
}
- (void) viewDidDisappear:(BOOL)animated
{
//restore the original implementation
Method originalStateWillChangeMethod = class_getInstanceMethod([UITableViewCell class], @selector(willTransitionToState:));
method_setImplementation(originalStateWillChangeMethod, originalStateWillChangeImplementation);
//rest of viewDidDisappear code
[super viewDidDisappear:animated];
}
Этот код может не соответствовать вашим точным целям, но я думаю, что он предоставляет полезный пример.
Это невероятно некрасиво, потому что метод customStateWillChange:
, определенный здесь, предназначен для запуска только как часть класса UITableViewCell, но в этом примере он будет скомпилирован, как если бы он был частью класса CustomTableController. Среди других неприятностей вам придется отказаться от нотации свойства точки, игнорировать предупреждения компилятора и отказаться от большинства, если не от всех проверок во время компиляции для тела этого метода.
Вариант 3 - Категория с магией выполнения
Именно так это звучит. Определите любые пользовательские методы изменения состояния, которые вам нравятся, внутри категории (или нескольких категорий) в UITableViewCell. Убедитесь, что у каждого есть отдельное имя - добавление двух категорий, в каждой из которых есть метод с одинаковым именем, приведет к неопределенному поведению. Кроме того, каждый из них должен иметь тот же тип возвращаемого значения и типы аргумента, что и метод, который он должен заменить.
Тогда ссылки на [self class] в приведенном выше коде будут заменены на [UITableViewCell class], а метод customStateWillChange:
будет перемещен в пользовательскую категорию. Хотя все еще некрасиво, вы можете по крайней мере положиться на компилятор, чтобы правильно интерпретировать тела метода.
Конечно, путаница со средой выполнения усложняет отслеживание. Он мог бы работать нормально, но это не очень хороший дизайн, потребовались бы серьезные усилия, чтобы обеспечить его безопасную и правильную работу, и это могло бы принести страдания и отчаяние любому, кто его поддерживает.
Ссылки
Язык программирования Objective-C - категории и расширения
Objective-C Runtime Reference