2014-09-24 1 views
12

Я реализовал автоматические высоты динамического TableView ячейки для прошивки 8 с помощьюКак переопределить метод в зависимости от версии iOS для системы исполнения?

self.tableView.rowHeight = UITableViewAutomaticDimension; 

Для предварительной прошивки 8, которая не поддерживают автоматические высоты динамической ячейки, я перекрытый метод heightForRowAtIndexPath.

Это похоже на то, что я сделал: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights

Проблемы заключается в том, как написать код, который использует автоматическую высоту ячейки для прошивки 8 но переопределяет heightForRowAtIndexPath для более ранних версий IOS. Мне нужен мой метод heightForRowAtIndexPath, только если версия iOS меньше 8. Любые предложения о том, как это сделать?

+3

Вы также могли бы рассмотреть только используя другой источник данных в iOS 7 и iOS 8. (т. е. объект другого класса) –

+0

@JesseRusak абсолютно прав, и это рекомендуемая практика. Создайте кластер классов для источника данных, который обеспечивает соответствующую конкретную реализацию во время выполнения. – quellish

ответ

19

Одним из решений было бы переопределить метод respondsToSelector: в вашем контроллере. Попросите его вернуть NO под iOS 8 при проверке метода heightForRowAtIndexPath:.

- (BOOL)respondsToSelector:(SEL)selector { 
    static BOOL useSelector; 
    static dispatch_once_t predicate = 0; 
    dispatch_once(&predicate, ^{ 
     useSelector = [[UIDevice currentDevice].systemVersion floatValue] < 8.0 ? YES : NO; 
    }); 

    if (selector == @selector(tableView:heightForRowAtIndexPath:)) { 
     return useSelector; 
    } 

    return [super respondsToSelector:selector]; 
} 

Таким образом, когда представление таблицы сделать вызов, как:

if ([self.delegate respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)]) { 
} 

код будет возвращать NO под прошивкой 8 или более поздней версии и YES под прошивкой 7 или выше.

+0

Я добавил это как категорию для 'UITableViewController', поэтому вам не нужно добавлять его к каждому. Также вы можете проверить, является ли селектор 'tableView: оценкамHeightForRowAtIndexPath:', поскольку я считаю, что это также не нужно для iOS8. – Koen

+0

@Koen Опасно переопределить метод в категории, поскольку это неопределенное поведение. Это может сработать, а может и нет. – rmaddy

+0

Хорошая точка, я удалю категорию и добавлю ее в каждый 'UITableViewController' – Koen

1

Я нашел простое решение. Заявленный этот макрос, чтобы признать, если пользователь имеет IOS 8.0 или более поздней версии:

#define IS_IOS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) 

Затем внутри heightForRowAtIndexPath я добавил следующий код:

if (IS_IOS_8_OR_LATER) { 
     self.tableView.rowHeight = UITableViewAutomaticDimension; 
     return self.tableView.rowHeight; 
    } else {//Custom code for ios version earlier than 8.0 

} 

Это решило проблему

+1

Недостатком этого подхода является то, что вы теряете много прироста производительности. Поскольку в таблице показано, что вы реализуете метод делегата 'heightForRowAtIndexPath', он вызывает его для каждой строки. Мое решение возвращает вам прирост производительности. – rmaddy

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