2013-09-23 18 views
9

Otrzymuję UITableViewCell UIButton należący do słuszne:Pierwsze UITableViewCell z SuperView w iOS 7

-(void)buttonHandler:(UIButton *)button { 

    OrderCell *cell = [[button superview] superview]; 
    NSLog(@"cell.item = %@", cell.item.text); 

i działa dobrze w niczym przed iOS 7. Ale daje mi:

[UITableViewCellScrollView pozycja]: nierozpoznany selektor wysyłane do instancji 0x17ae2cf0

jeśli uruchomić aplikację w iOS 7. Ale jeśli zrobić:

-(void)buttonHandler:(UIButton *)button { 

    OrderCell *cell = [[[button superview] superview] superview]; 
    NSLog(@"cell.item = %@", cell.item.text); 

Następnie działa w systemie iOS 7, ale nie wcześniej?!?!?!

mam obejście problemu w ten sposób:

OrderCell *cell; 
if([[[UIDevice currentDevice] systemVersion] isEqualToString:@"7.0"]) 
    cell = [[[button superview] superview] superview]; 
else 
    cell = [[button superview] superview]; 

NSLog(@"cell.item = %@", cell.item.text); 

ale WTF się dzieje !? Czy ktoś wie, dlaczego tak się dzieje?

Dzięki!

+2

Twój kod został zależności od prywatnej struktury podrzędny z 'UITableViewCell '. Oczywiście struktura ta uległa zmianie w iOS 7. Istnieje wiele bezpieczniejszych sposobów robienia tego, co chcesz. Twój nowy kod zostanie złamany w systemie iOS 7.1 i iOS 8. – rmaddy

+0

@rmaddy Jaka jest bezpieczniejsza metoda? – Mundi

+1

Można iterować przez superviews, sprawdzając, czy są one typu klasy UITableViewCell, a następnie zwrócić ten widok? Zobacz odpowiedź: – CW0007007

Odpowiedz

27

Lepszym rozwiązaniem jest, aby dodać kategorię dla UIView (Superview) i nazywając go:

UITableViewCell *cell = [button findSuperViewWithClass:[UITableViewCell class]] 

ten sposób Twój kod działa na wszystkich wersjach przyszłe i przeszłe iOS

@interface UIView (SuperView) 

- (UIView *)findSuperViewWithClass:(Class)superViewClass; 

@end 


@implementation UIView (SuperView) 

- (UIView *)findSuperViewWithClass:(Class)superViewClass { 

    UIView *superView = self.superview; 
    UIView *foundSuperView = nil; 

    while (nil != superView && nil == foundSuperView) { 
     if ([superView isKindOfClass:superViewClass]) { 
      foundSuperView = superView; 
     } else { 
      superView = superView.superview; 
     } 
    } 
    return foundSuperView; 
} 
@end 
+9

Ten kod można poprawić dodając 'break' po znalezieniu pasującego superview. Nie trzeba za każdym razem podchodzić do okna. – rmaddy

-2
if ([[button superView] isKindOfClass:[UITableViewCell class]]) { 

} 

else //check next : 
13

najlepszym sposobem, aby to zrobić:

CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView]; 
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition]; 
UITableViewCell *cell = (UITableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath]; 
+0

Najlepsza odpowiedź, bardzo rzetelna decyzja – zest

3

Aby zakończyć odpowiedź @ Thomas-keuleers to szybka metoda:

extension UIView { 

    func findSuperViewWithClass<T>(superViewClass : T.Type) -> UIView? { 

     var xsuperView : UIView! = self.superview! 
     var foundSuperView : UIView! 

     while (xsuperView != nil && foundSuperView == nil) { 

      if xsuperView.self is T { 
       foundSuperView = xsuperView 
      } else { 
       xsuperView = xsuperView.superview 
      } 
     } 
     return foundSuperView 
    } 

} 

i po prostu nazwać tak:

child.findSuperViewWithClass(TableViewCell) 
+0

child.findSuperViewWithClass (TableViewCell.self) – sasquatch

Powiązane problemy