2017-06-20 5 views
0

Es gibt eine große Anzahl von Fragen zu diesem Thema, aber ich bin noch nicht über meinen Anwendungsfall so hier ist.Objective-c UITableView separate Klasse cellForRowAtIndexPath wird nicht aufgerufen

Dies ist mein erstes Paar Wochen in OBJ-C, damit ich keine Ahnung, was ich mit einigen dieser Sachen tue ...

What I Want

ich besonders nicht in den Genuss zu sehen, so viele Klassen in OBJ-C, die die View-Controller-Klassen mit jeder Funktion auf dieser Erde überladen. Es sieht schmutzig aus und fühlt sich so grob an, wie OOP es geht. In meinem Anwendungsfall habe ich keinen vollen Bildschirm Tisch nur ein kleines, um 10 Dinge zu halten. Daher ist es ziemlich unangebracht, einen vollständigen UITableViewController zu verwenden. Stattdessen möchte ich alle meine Tabellen Delegate spezifische Methoden in einer UITableView-Unterklasse haben. NICHT in einem UITableViewController oder einem ViewController mit einer UITableView-Eigenschaft. Dies sollte doch einfach mega sein ...

Das Problem

Egal was ich tue, ich kann nicht cellForRowAtIndexPath abzufeuern, die Methode zu bekommen scheinen. Ich weiß genug, um zu wissen, dass dieses Zeug stark von der Delegierten- und Datenquellenzuweisung abhängt ... aber da ich eine separate UITableView-Klasse habe, die die <UITableViewDelegate, UITableViewDataSource> Delegationen verwendet, glaube ich nicht, dass ich irgendeine Art von Aufgabe ausführen sollte!

Was soll ich schreiben ?? self.delegate = self? oder schlimmer, in der ViewController, die diese UITableView-Klasse aufruft, self.tasksTable.delgate = self.tasksTable? Eww ... brutto

Hier ist, was ich im Code tue.

Der Kodex

TasksTableView.h

#import <UIKit/UIKit.h> 

@interface TasksTableView : UITableView <UITableViewDelegate, UITableViewDataSource> { 
    NSArray *tasksData; 
} 

- (NSMutableArray *)getAllTasks; 

@end 

TasksTableView.m

#import "TasksTableView.h" 
#import "NSObject+RemoteFetch.h" //<--I use this to fetch, obvs 

@interface TasksTableView() 
@property (nonatomic, strong) NSString *cellId; 
@end 


@implementation TasksTableView 

- (instancetype)initWithCoder:(NSCoder *)coder { 
    self = [super initWithCoder:coder]; 

    if(self) { 
     _cellId = @"AllTasksTableCell"; 
     tasksData = [self getAllTasks]; 
    } 

    return self; 
} 


#pragma mark - Custom Table Functionality 

- (NSMutableArray *)getAllTasks { 
    @try { 
     NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
     NSString *TASKS_URL = [userDefaults objectForKey:@"tasksUrl"]; 

     NSObject *fetcher = [[NSObject alloc] init]; 
     NSDictionary *response = [fetcher fetchAPICall:TASKS_URL httpRequestType:@"GET" requestBodyData:nil]; 

     return [response objectForKey:@"data"]; 

    } @catch (NSException *exception) { 
     NSLog(@"could not get tasks, error: %@", exception); 

     return nil; 
    } 
} 


#pragma mark - UITableView DataSource Methods 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [tasksData count]; 
} 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    //<-- NEVER GETS HERE 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:_cellId]; 

    if(cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:_cellId]; 
    } 

    cell.textLabel.text = [tasksData objectAtIndex:indexPath.row]; 

    return cell; 
} 

@end 

Ich bin auch eine harte Zeit, herauszufinden, was mit als die festlegen Datenquelle. In anderen Sprachen würden Sie das DataSource-Objekt normalerweise mit self.DataSource = [self getAllTasks] ... setzen ... aber alle Tutorien, die ich bisher gemacht habe, neigen dazu, irgendein seltsames Ad-hoc-NSArray oder NSDictionary zu verwenden, um dann den Index der Tabellenfunktionen mit dem Index der Array- oder Dictionary-Keys ... Das verwirrt mich sehr, warum ich nicht einfach das DataSource-Objekt setzen und die Tabelle wissen lassen kann, dass sie über ihre Daten iterieren soll.

Meine Schlussfolgerung ist, dass dies nicht feuert, weil es denkt, dass das DataSource-Objekt leer ist und es keine Zeilen gibt? (was es ist, aber wie ich schon sagte, die Leute scheinen Tische zu bekommen, damit sie auf YouTube gut funktionieren)

Danke.

+0

In 'initWithCoder auslösen wird:', versuche, 'self.dataSource = self 'zu machen. – Larme

+0

Ich hatte wirklich WIRKLICH gehofft, dass das nicht die Antwort sein würde :(das ist so eklig. – GoreDefex

+0

@Larme yep, die es getan haben :(eine Antwort einreichen, so kann ich diese Frage aufwerten und abschließen. Danke – GoreDefex

Antwort

1

TasksTableView Klasse ist abgeleitet von UITableView Klasse & Sie implementieren die UITableview Delegierten in der gleichen Klasse. Dies wird nicht funktionieren.

Anstatt eine UITableView Unterklasse zu erstellen. Erstellen Sie TasksTableView Klasse als NSObject Unterklasse.Und übergeben Sie das tableview Objekt, von dem Sie eine tableview hinzugefügt haben.

@interface TasksTableView : NSObject <UITableViewDelegate, UITableViewDataSource> { 
    NSArray *tasksData; 
    __weak UITableView *tableView; 
} 

Und das Tabellenansicht Delegierten gesetzt (Objekt TasksTableView) zu self während init die TasksTableView Klasse

- (instancetype)initWithCoder:(NSCoder *)coder { 
    self = [super initWithCoder:coder]; 

    if(self) { 
     _cellId = @"AllTasksTableCell"; 
     tasksData = [self getAllTasks]; 
     self.tableView.delgate = self; 
     self.tableView.datasource = self; 
    } 

    return self; 
} 

nun Ihre delegate Methoden für die jeweilige tableview

+0

Ja, das fühlt sich ein bisschen besser an als selbst .delegate = selbst ... Nicht viel ein bisschen besser. – GoreDefex

+0

Ich dachte gerade, da ich UITableView bereits subclassing war, dass es klar sein sollte, dass Delegat/Datenquelle selbst ist. – GoreDefex

Verwandte Themen