Frage

Es nervt mich zu Tode, dass meine Viewcontroller, die eine Tableviewcontroller sein geschieht, weiß, ohne gesagt, dass seine Eigenschaft, dass ein NSArray oder ein NSDictionary die Daten enthält, die in der Tabelle für die Anzeige geladen werden soll.

Scheint, wie ich ausdrücklich etwas wie sagen sollte:

[self.tableView useData:self.MyArray];

Ich möchte mehr als ein Array in meinem Tableviewcontroller und Schalter zwischen einem und dem anderen programmatisch haben.

Ich stelle fest, dass, wenn eine Tableviewcontroller Verwendung eines searchViewController macht, können Sie dies tun:

if (tableView == self.searchDisplayController.searchResultsTableView) {

Ich habe sogar in der Lage gewesen, dies zu tun:

self.tableView =  self.searchDisplayController.searchResultsTableView;
[self.tableView reloadData];

Aber nirgends finde ich, wie man Satz self.tableView zurück zum Hauptdatenquelle!

War es hilfreich?

Lösung

Okay, ich verstehe Ihre Frustration, weil die überwiegende Mehrheit des iPhone Lehrmaterials nicht genügend Aufmerksamkeit Gesamt App Design bezahlen. Sie machen einen Abstecher zum Augenschmaus Schnittstelle und zahlen nur Lippenbekenntnisse Art und Weise, dass die App die Daten verarbeiten sollte obwohl die Datenverarbeitung ist der ganze Zweck der App in den ersten Platz!

Die Unterrichtsmaterialien verbringen nicht genug Zeit, um das Model-View-Controller-Entwurfsmuster zu erklären, auf das der gesamte iPhone / Cocoa-API basiert. Sie haben eine harte Zeit, etwas zu verstehen, weil Sie zu stopfen Funktionalität in die falschen Objekte unter dem irrigen Glauben, immer wieder versuchen, dass die UI-Ansicht der Kern des Programms ist es, da die Unterrichtsmaterialien Sie haben zu glauben. Unter diesem Mißverständnis, macht nichts Sinn, nicht einmal auf die Apple-Dokumentation.

Sie müssen einen Schritt zurück und umdenken. Es ist nicht die Funktion einer Ansicht, um zu entscheiden, welche Daten und, wenn angezeigt wird, um sie anzuzeigen. Es ist nicht die Funktion der Tabelle View-Controller zu halten, verwalten oder die Daten der App speichern. Diese Funktionen richtig, gehören in das Datenmodell Objekt (das haben Sie vielleicht noch nie gehört.) Sie haben Probleme, weil Sie versuchen, das Datenmodell Aufgabe für die Ansicht und die View-Controller aufgeteilt waren sie nicht gehören.

Offenbar Ihre App noch nicht einmal ein Datenmodell, weil Sie die Daten der Tabelle als Eigenschaften des Tableview Controller halten. Obwohl Sie oft diese sehen in verein Tutorial Beispiele, ist es schlechtes Design, die unter der Komplexität jeder kollabieren, aber die banalsten Apps.

Stattdessen sollten Ihre Daten in und in seinem eigenen benutzerdefinierten Objekt verwaltet gespeichert werden. Dies ist das Datenmodell. In Ihrem Fall, es klingt wie Sie Daten verteilt auf zwei Arrays, so dass Sie ein Datenmodell Objekt so etwas wie dies schaffen würde:

@interface MyDataModel : NSObject {
@protected
    NSArray *arrayOne;
    NSArray *arrayTwo;
@public
    NSArray *currentlyUsedArray;

}
@property(nonatomic, retain)  NSArray *currentlyUsedArray;

-(void) switchToArrayOne;
-(void) switchToArrayTwo;
-(void) toggleUsedArray;

@end

#import "MyDataModel.h"

@interface MyDataModel ()
@property(nonatomic, retain)  NSArray *arrayOne;
@property(nonatomic, retain)  NSArray *arrayTwo;

@end


@implementation MyDataModel

- (id) init{
    if (self=[super init]) {
        self.arrayOne=//... initialize array from some source
        self.arrayTwo=//... initialize array from some source
        self.currentlyUsedArray=self.arrayOne; //whatever default you want
    }
    return self;
}

-(void) switchToArrayOne{
    self.currentlyUsedArray=self.arrayOne;
}

-(void) switchToArrayTwo{
    self.currentlyUsedArray=self.arrayTwo;
}

- (void) toggleUsedArray{
    if (self.currentlyUsedArray==self.arrayOne) {
        self.currentlyUsedArray=self.arrayTwo;
    }else {
        self.currentlyUsedArray=self.arrayOne;
    }
}

(Beachten Sie, dass die eigentlichen Daten verkapselt sind und die anderen Objekte können nur die currentlyUsedArray zugreifen. Das Datenmodell entscheidet, die Daten basierend auf dem internen Zustand der Daten zu liefern.)

Dieses Datenmodell-Objekt sollte in einem allgemein zugänglichen Ort sein. Die beste Methode ist es ein Singleton zu machen, aber die schnelle und schmutzige Methode ist es, als ein Attribut des AppDelegate zu parken.

So in Sie Tableview Controller würden Sie eine Eigenschaft haben:

MyDataModel *theDataModel;
@property (nonatomic, retain) MyDataModel *theDataModel;

dann bei der Umsetzung

@synthesize theDataModel;

-(MyDataModel *) theDataModel; {
    if (theDataModel; !=nil) {
        return theDataModel; ;
    }
    id appDelegate=[[UIApplication sharedApplication] delegate];
    self.theDataModel=appDelegate.theDataModelProperty;
    return theDataModel;
}

Dann in Ihrer Tableview Datasource-Methode:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    ...
    cell.textLabel.text=[self.theDataModel.currentlyUsedArray objectAtIndex:indexPath.row];
    return cell;
}

Wenn ein Ereignis überall in der App Sie erfordert Arrays zu wechseln, müssen Sie nur das Datenmodell-Objekt aus dem AppDelegate aufrufen und die entsprechende Schalteranordnung Nachricht senden .

id appDelegate=[[UIApplication sharedApplication] delegate];
[appDelegate.theDataModelProperty toggleUsedArray];

Nun wird alle nachfolgenden Datenoperationen, ob in dieser bestimmten Tabellenansicht oder eine anderen völlig unabhängig Ansicht, werden die Daten verwenden, um die richtige Anordnung bilden.

Warum sollten Sie sich diese Mühe? Es macht die Anwendung modular. Sie können, ohne auf eine andere Art und Weise auf verschiedene Ansichten, von denen jede die Daten anzeigen umschreiben Ihre Datenverwaltung jedes Mal leicht hinzufügen. Sie können das Datenmodell verwenden, um Daten zu verwalten, die in einer Tabelle angezeigt werden, in einer Webansicht oder auf der Kommandozeile. Sie können auch leicht das Datenmodell zu einem ganz anderen App bewegen.

Diese Modularität macht das Management von großen, komplexen Anwendungen so viel einfacher. Sie haben nur ein Objekt, das manipuliert und steuert die Daten. Sie müssen sich keine Sorgen machen, dass einige kleinere Fehler in einigen selten verwendeten Codesegment wird die gesamte App Müll. Sie können Ansichten leicht Plugin oder sie leicht entfernen, ohne die App zu brechen.

Das ist natürlich ein triviales Beispiel, aber es zeigt eine gute Praxis.

Sie können jedoch fragen, wie dies das Problem der Tableview löst, welche Daten zu Last zu wissen, und wenn es zu laden? Einfach, nicht. Es ist nicht die Aufgabe des Tableview zu wissen, whauf Daten laden oder zu laden, wenn. Das Datenmodell Greift die Was-sei-Daten und Tableview-Controller übernehmen die bei. (Sie können auch die Datenmodell Ausgabe Meldungen haben, wenn es für eine URL beispielsweise aktualisiert wird. Dann die View-Controller für die Benachrichtigung und Call reloadData registrieren können, wenn die Datenmodelländerungen.)

Durch die konsequente Kompartimentierung und Einkapseln Funktionalität in MVC, erstellen Sie komplexe Anwendungen von einfachen, wiederverwendbaren Komponenten, die leicht zu pflegen und zu debuggen sind.

Es ist wirklich zu schlecht den meisten Unterrichtsmaterialien nur Lippenbekenntnisse zu diesem äußerst kritischen Konzept zahlen.

Andere Tipps

Ein Controller der Tabellenansicht nicht „kennt, ohne gesagt,“ anything-- es nicht von Natur aus keine Eigenschaft haben, wie Sie diese Daten erwähnen herkommt. Sie liefern diese Daten, eine Zelle zu einer Zeit, in der Regel in Ihrer View-Controller-Unterklasse.

Normalerweise Tisch-View-Controller-Objekt ist sowohl die Delegierten Tabellenansicht und die Datenquelle Delegierten Tabellenansicht. Aus dem Apple-docs:

  

Ein UITableView Objekt muss eine haben   delegieren und eine Datenquelle. folgende   das Model-View-Controller-Design   Muster, vermittelt die Datenquelle   zwischen dem Datenmodell der Anwendung   (Das heißt, Objekte sein Modell) und die   Tabellenansicht; die Delegierten auf der anderen Seite   Seits schafft das Aussehen und   Verhalten der Tabellenansicht. Die Daten   Quelle und die Delegierten sind oft (aber   nicht notwendigerweise) das gleiche Objekt, und   Diese Aufgabe wird häufig eine benutzerdefinierte   Unterklasse von UITableViewController.

Die Tabellenansicht findet nicht in einem Array oder einem Wörterbuch und Pull-Daten aus; es fordert Sie in Ihrer Datenquelle, was jede Zelle aussehen sollte. Sie implementieren gerade diese Methode:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Und Rückkehr was Inhalt in einer Zelle, die Sie für die Zeile wir Sie wollen gefragt. Sie können dort setzen Logik mischen / Spiel / Pull-Daten aus, wo immer Sie wollen.

Könnte Ihre Verwirrung aus einer Suppe von Beispielcode kommen vielleicht die etwa unklar ist, was ist los? Ich würde empfehlen, eine Tabellenansicht von Grund auf neu zu sehen, wie diese works-- es ist einfach, dies zu tun, indem sie eine neue Klasse zu Ihrem Projekt hinzufügen, können Sie eine UITableViewController Unterklasse von innen XCode in der „neuen“ Assistenten auswählen können. Es wird die .m-Datei mit allen relevanten leeren Methoden, einschließlich der oben vorab ausgefüllt.


EDIT: Ziehen Sie nicht die Tabelle anzeigen ändern Sie Ihren View-Controller besitzt, wenn die Suche. Du verwechselst die Instanz Referenz genannt „Tableview“, die Ihre View-Controller, mit dem Argument der Delegatmethode tableView:cellForRowAtIndexPath: besitzt, die gerade in geben wird immer Ihnen sagen, , die Tabellenansicht für ein bittet Zelle. Wenn Sie in gewohnter Weise mit der gleichen Viewcontroller ist der Delegierte sowohl für den Standard / Inhaltstabelle und die Suchergebnisse Suche eingerichtet haben, können Sie entweder mit aufgerufen. sehen Sie hier für die Dokumentation zu diesem .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top