2013-09-23 9 views
9

Ich erhalte die UITableViewCell ein UIButton dies gerne gehört:Erste UITableViewCell mit Superview in iOS 7

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

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

Und es funktioniert in etwas vor iOS 7. Ordnung, aber gibt mir:

[UITableViewCellScrollView Artikel]: Unbekannter Selektor an Instanz gesendet 0x17ae2cf0

wenn ich die app in iOS 7 laufen, aber wenn ich es tue:

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

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

Dann funktioniert es in iOS 7 aber nicht früher?!?!?!

ich umgehen das Problem, indem dies zu tun:

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); 

aber WTF ist los !? Weiß jemand, warum das passiert?

Danke!

+2

Der Code wurde in Abhängigkeit von der privaten subview Struktur von 'UITableViewCell '. Offensichtlich hat sich diese Struktur in iOS 7 geändert. Es gibt viel sicherere Möglichkeiten, um das zu tun, was Sie wollen. Und Ihr neuer Code wird unter iOS 7.1 und iOS 8 brechen. – rmaddy

+0

@rmaddy Was ist der sicherere Weg? – Mundi

+1

Sie könnten die Superviews durchlaufen, prüfen, ob sie vom Klassentyp UITableViewCell sind, und dann diese Ansicht zurückgeben? Siehe Antwort: – CW0007007

Antwort

27

Eine bessere Lösung ist eine Kategorie für UIView (Super) hinzuzufügen, und es durch den Aufruf:

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

diese Weise Ihr Code funktioniert für alle Zukunft und Vergangenheit iOS Versionen

@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

Dieser Code kann verbessert werden, indem ein "Break" hinzugefügt wird, sobald Sie den passenden Superview gefunden haben. Keine Notwendigkeit, jedes Mal bis zum Fenster zu gehen. – rmaddy

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

} 

else //check next : 
13

Der beste Weg, dies zu tun ist:

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

Beste Antwort, sehr zuverlässige Entscheidung – zest

3

Um die Antwort von @ thomas-keuleers zu vervollständigen das ist die schnelle Methode:

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 
    } 

} 

und man einfach so nennen:

child.findSuperViewWithClass(TableViewCell) 
+0

child.findSuperViewWithClass (TableViewCell.self) – sasquatch