IOS 8: - [UITableViewWrapperView textField]: непризнанный селектор, отправленный в экземпляр
Привет. Я тестировал свое приложение на iOS 6, 7 и теперь 8 (бета-версия 5). Мой UITableView
с пользовательским UITableViewCell
работает нормально на 6 и 7. Однако на iOS 8 я получаю сбой при попытке получить доступ к подсмотру (текстовому полю) ячейки.
Мне известно о том, что в iOS 7 есть другой вид в иерархии ячеек. Как ни странно, похоже, что это не так в iOS 8. Вот код, который я использую:
//Get the cell
CustomCell *cell = nil;
//NOTE: GradingTableViewCell > UITableViewCellScrollView (iOS 7+ ONLY) > UITableViewCellContentView > UIButton (sender)
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
cell = (CustomCell *)sender.superview.superview;
} else {
cell = (CustomCell *)sender.superview.superview.superview;
}
//Get the cell index path
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
//etc.
NSLog(@"%@", cell.textField); //<---Crashes here
Итак, как вы можете видеть, я учитываю дополнительный вид в iOS 7. После добавления некоторых точек останова и более пристального взгляда на переменные я вижу, что cell
существует, но все подзаголовки, которые он имеет в файл интерфейса (который связан) - включая textField
- - nil
. В указанной строке я получаю следующий журнал сбоев:
-[UITableViewWrapperView textField]: unrecognized selector sent to instance 0x12c651430
Я изучил это дальше, и я нашел это:
Изменение оператора else
идентично предыдущей строке избавляет от сбоя, и приложение работает нормально (используя sender.superview.superview
, как в iOS 6).
Это не имеет никакого смысла для меня. Apple вернула иерархию UITableViewCell
к иерархии iOS 6, или я что-то упустил? Спасибо!
Ответы
Ответ 1
Я столкнулся с той же проблемой. Здесь более надежный метод:
UITextField* textField = (UITextField*)sender;
NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:[self.tableView convertPoint:textField.center fromView:textField.superview]];
Это будет работать независимо от базовой иерархии представлений UITableViewCell.
Ответ 2
Различные версии iOs имеют разные реализации UITableView
или UITableViewController
, поскольку вам нужно будет выполнять итерацию через superviews
, пока вы не найдете нужный класс представления, вместо того чтобы полагаться на него как на N-й супервизор.
Ответ 3
У меня также была такая же проблема на iOS8 с получением UITableViewCell через супервизор из дочернего представления. Это то, что я придумал для поддержки iOS7 и iOS8.
-(void)thumbTapped:(UITapGestureRecognizer*)recognizer {
NSLog(@"Image inside a tableview cell is tapped.");
UIImageView *mediaThumb = (UIImageView*)recognizer.view;
UITableViewCell* cell;
// get the index of container cell row
// bug with ios7 vs ios8 with superview level!! :(
/*** For your situation the level of superview will depend on the design structure ***/
// The rule of thumb is for ios7 it need an extra superview
if (SYSTEM_VERSION_LESS_THAN(@"8.0")) { // iOS 7
cell = (UITableViewCell*)mediaThumb.superview.superview.superview.superview;
} else { // iOS 8
cell = (UITableViewCell*)mediaThumb.superview.superview.superview;
}
}
Чтобы уточнить, в cellForRowAtIndexPath я назначил распознаватель жестов. Оригинальный дизайн очень сложный в раскадровке с множеством подзонов, кнопок и т.д.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MediaCell" forIndexPath:indexPath];
.......
UIImageView *mediaImage = ............
.....................................
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(thumbTapped:)];
[mediaImage addGestureRecognizer:tapGestureRecognizer];
return cell;
}