Сбой UITableViewCell indexPath в iOS7

У меня UITableViewCell в UITableViewController. В моей камере есть кнопка, которая при нажатии переводит вас на другой view с prepareforsegue. В prepareForSegue я делаю это:

if ([[segue identifier] isEqualToString:@"MySegue"])
{
    UITableViewCell *cell = (UITableViewCell*) [[sender superview] superview];
    UITableView *table = (UITableView*)[[[sender superview] superview] superview];
    NSIndexPath *indexPath = [table indexPathForCell:cell]; 
}

В порядке! Все всегда работало хорошо. Но теперь, когда я обновил xCode до iOS7, когда я нажимаю кнопку, расположенную в ячейке, мне выдается ошибка, и я не знаю, как ее решить:

[UITableViewCell indexPathForCell:]: unrecognized selector sent to instance 0x9e160b0
2013-09-20 16:30:44.427 MyApp[8212:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewCell indexPathForCell:]: unrecognized selector sent to instance 0x9e160b0'
*** First throw call stack:
(
    0   CoreFoundation                      0x024475e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x01a5d8b6 objc_exception_throw + 44
    2   CoreFoundation                      0x024e4903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
    3   CoreFoundation                      0x0243790b ___forwarding___ + 1019
    4   CoreFoundation                      0x024374ee _CF_forwarding_prep_0 + 14
    5   MyApp                              0x0004bc01 -[NewsTableViewController prepareForSegue:sender:] + 3441
    6   UIKit                               0x00af69cc -[UIStoryboardSegueTemplate _perform:] + 156
    7   UIKit                               0x00af6a59 -[UIStoryboardSegueTemplate perform:] + 115
    8   libobjc.A.dylib                     0x01a6f874 -[NSObject performSelector:withObject:withObject:] + 77
    9   UIKit                               0x005c4c8c -[UIApplication sendAction:to:from:forEvent:] + 108
    10  UIKit                               0x005c4c18 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
    11  UIKit                               0x006bc6d9 -[UIControl sendAction:to:forEvent:] + 66
    12  UIKit                               0x006bca9c -[UIControl _sendActionsForEvents:withEvent:] + 577
    13  UIKit                               0x006bbd4b -[UIControl touchesEnded:withEvent:] + 641
    14  UIKit                               0x00936d7f _UIGestureRecognizerUpdate + 7166
    15  UIKit                               0x00601d4a -[UIWindow _sendGesturesForEvent:] + 1291
    16  UIKit                               0x00602c6a -[UIWindow sendEvent:] + 1030
    17  UIKit                               0x005d6a36 -[UIApplication sendEvent:] + 242
    18  UIKit                               0x005c0d9f _UIApplicationHandleEventQueue + 11421
    19  CoreFoundation                      0x023d08af __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    20  CoreFoundation                      0x023d023b __CFRunLoopDoSources0 + 235
    21  CoreFoundation                      0x023ed30e __CFRunLoopRun + 910
    22  CoreFoundation                      0x023ecb33 CFRunLoopRunSpecific + 467
    23  CoreFoundation                      0x023ec94b CFRunLoopRunInMode + 123
    24  GraphicsServices                    0x032c89d7 GSEventRunModal + 192
    25  GraphicsServices                    0x032c87fe GSEventRun + 104
    26  UIKit                               0x005c394b UIApplicationMain + 1225
    27  MyApp                              0x00002cfb main + 235
    28  libdyld.dylib                       0x01f42725 start + 0
    29  ???                                 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Строка, в которой приложение вылетает, такова:

    NSIndexPath *indexPath = [table indexPathForCell:cell]; }

person Pinturikkio    schedule 20.09.2013    source источник


Ответы (6)


В iOS7 UITableViewWrapperView является суперпредставлением UITableViewCell, что означает для вас другое суперпредставление:

iOS7:

UITableView *tableView = (UITableView *)cell.superview.superview;

iOS6"

UITableView *tableView = (UITableView *)cell.superview;

Еще одно изменение вы можете найти здесь:

кажется, ваш код: UITableView table = (UITableView)[[[sender superview] superview] superview]; возвращает UITableViewCell, а не UITableView.

Попробуйте следующее:

UITableView *table = (UITableView*)[[[[[sender superview] superview] superview] superview] superview];
person Tarek Hallak    schedule 20.09.2013
comment
В iOS 8 иерархия представлений похожа на iOS 6, поэтому снова используйте непосредственное суперпредставление. - person Matti Jokipii; 19.07.2015

Apple меняет иерархию UITableViewCell в iOS 7

Использование iOS 6.1 SDK

<UITableViewCell>
   | <UITableViewCellContentView>
   |    | <UILabel>

Использование SDK для iOS 7

<UITableViewCell>
   | <UITableViewCellScrollView>
   |    | <UITableViewCellContentView>
   |    |    | <UILabel>

Итак, если вы хотите получить indexpath в индексе кнопки, используйте следующий код. Использование iOS 6 или более поздней версии SDK

UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
    NSIndexPath *clickedButtonPath = [book_table indexPathForCell:clickedCell];
    NSLog(@"index=%@",clickedButtonPath);

Использование iOS 7 или 7+ SDK

UITableViewCell *clickedCell = (UITableViewCell *)[[[sender superview] superview]superview];
    NSIndexPath *clickedButtonPath = [book_table indexPathForCell:clickedCell];
    NSLog(@"index=%ld",(long)clickedButtonPath.item);
person Bhoopi    schedule 07.10.2013

Это работает точно, но как супер мы можем получить?

person chinjazz    schedule 03.10.2013

У меня была аналогичная проблема, когда мне нужно было найти значение textFileds из TableView.

if ([Util isiOSVerGreaterThen7]) { // iOS 7
            UIView *contentView = (UIView *)[textField superview];
            UITableViewCell *cell = (UITableViewCell *)[contentView superview];
            UITableView *tableView = (UITableView *)cell.superview.superview;
            NSIndexPath *indexPath = [tableView indexPathForCell:cell];

            NSInteger sectionOfTheCell = [indexPath section];
            NSInteger rowOfTheCell = [indexPath row];
        }
        else { // iOS 6
            UITableViewCell *cell = (UITableViewCell *)[textField superview];
            UITableView *table = (UITableView *)[cell superview];
            NSIndexPath *pathOfTheCell = [table indexPathForCell:cell];
            NSInteger sectionOfTheCell = [pathOfTheCell section];
            NSInteger rowOfTheCell = [pathOfTheCell row];
        }

И Утиль есть

+ (BOOL)isiOSVerGreaterThen7 {
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
        return NO;
    } else {
        return YES;
    }
}
person Bishal Ghimire    schedule 29.10.2013

Это лучше использовать

NSIndexPath *indexPath = [self.callTable indexPathForCell:(UITableViewCell *)[[[sender superview] superview] superview]];
    NSLog(@"%d",indexPath.row);
person user366584    schedule 25.12.2013

Это лучший способ, я думаю:

CGPoint subviewPosition = [отправитель convertPoint:CGPointZero toView:self.myTable];

NSIndexPath * indexPath = [self.myTable indexPathForRowAtPoint: subviewPosition];

Вы можете просто получить индексный путь здесь. Будь то iOS7 или iOS6, он вернет правильный путь к индексу.

person Gautam Jain    schedule 09.04.2014