• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Viele hassen ihn, manche schwören auf ihn, wir aber möchten unbedingt sehen, welche Bilder Ihr vor Eurem geistigen Auge bzw. vor der Linse Eures iPhone oder iPad sehen könnt, wenn Ihr dieses Wort hört oder lest. Macht mit und beteiligt Euch an unserem Frühjahrsputz ---> Klick

TableView mit NSArray durchsuchen

branco145

Rheinischer Winterrambour
Registriert
26.07.09
Beiträge
933
Hallo,

ich habe ein kleines App, der eine Tabelle mit Begriffen anzeigt, momentan noch aus einem NSArray.

View1.h
Code:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

@interface Dienstgrade : UIViewController /* Specify a superclass (eg: NSObject or NSView) */ {
	NSArray *things;
	IBOutlet UITableView *tableView;
	
}

- (IBAction)back;

@end

Und in der .m Datei
Code:
#import "Dienstgrade.h"
#import "DienstgradeDetailViewController.h"

@implementation Dienstgrade

- (void)viewDidLoad {
    [super viewDidLoad];
	things = [[NSArray alloc] initWithObjects:
			  @"Schtz",
			  @"Fu",
			  @"Fig",
			  @"Gren",
			  @"Jg",
			  @"Kan",
			  @"Matr",
			  @"Pi",
			  @"PzFu",
			  @"PzGren",
			  @"PzJg",
			  @"PzKan",
			  @"PzPi",
			  @"PzSchtz",
			  @"PzSdt",
			  @"Gefr",
			  @"OGefr",
			  @"HptGefr",
			  @"StGefr",
			  @"OStGefr",
			  nil];
}

#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [things count];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
		cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    
    
	cell.text = [things objectAtIndex:indexPath.row];
    return cell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    DienstgradeDetailViewController *rdc = [[DienstgradeDetailViewController alloc] initWithNibName:@"RecipeDetailView" bundle:nil];
	rdc.title = [things objectAtIndex:indexPath.row];
	
	
	switch (indexPath.row) {
		case 0:
			rdc.rezeptText = @"Die Abkürzung 'Schtz' bedeutet Schütze.";
			break;
		case 1:
			rdc.rezeptText = @"Die Abkürzung 'Fu' bedeutet Funker.";
			break;
		case 2:
			rdc.rezeptText = @"Die Abkürzung 'Fig' bedeutet Flieger.";
			break;
		case 3:
			rdc.rezeptText = @"Die Abkürzung 'Gren' bedeutet Grenadier.";
			break;
			
		case 4:
			rdc.rezeptText = @"Die Abkürzung 'Jg' bedeutet Jäger.";
			break;
		case 5:
			rdc.rezeptText = @"Die Abkürzung 'Kan' bedeutet Kanonier.";
			break;
		case 6:
			rdc.rezeptText = @"Die Abkürzung 'Matr' bedeutet Matrose.";
			break;
		case 7:
			rdc.rezeptText = @"Die Abkürzung 'Pi' bedeutet Pionier.";
			break;
		case 8:
			rdc.rezeptText = @"Die Abkürzung 'PzFu' bedeutet Panzerfunker.";
			break;
		case 9:
			rdc.rezeptText = @"Die Abkürzung 'PzGren' bedeutet Panzergrenadier.";
			break;
		case 10:
			rdc.rezeptText = @"Die Abkürzung 'PzJg' bedeutet Panzerjäger.";
			break;
		case 11:
			rdc.rezeptText = @"Die Abkürzung 'PzKan' bedeutet Panzerkanonier.";
			break;
		case 12:
			rdc.rezeptText = @"Die Abkürzung 'PzPi' bedeutet Panzerpionier.";
			break;
		case 13:
			rdc.rezeptText = @"Die Abkürzung 'PzSchtz' bedeutet Panzerschütze.";
			break;
		case 14:
			rdc.rezeptText = @"Die Abkürzung 'PzSdt' bedeutet Panzersoldat.";
			break;
		case 15:
			rdc.rezeptText = @"Die Abkürzung 'Gefr' bedeutet Gefreiter.";
			break;
		case 16:
			rdc.rezeptText = @"Die Abkürzung 'OGefr' bedeutet Obergefreiter.";
			break;
		case 17:
			rdc.rezeptText = @"Die Abkürzung 'HptGefr' bedeutet Hauptgefreiter.";
			break;
		case 18:
			rdc.rezeptText = @"Die Abkürzung 'StGefr' bedeutet Stabsgefreiter.";
			break;
		case 19:
			rdc.rezeptText = @"Die Abkürzung 'OStGefr' bedeutet Oberstabsgefreiter.";
			break;
			
		default:
			break;
			
	}
	
	[self presentModalViewController:rdc animated:YES];
	[rdc release];
}


- (IBAction)back {
	
	[self dismissModalViewControllerAnimated:YES];
	
	
}


@end

Das Problem ist ja nun erstmal schon, das ich jeder Tabellenspalte einen festen Wert gegeben hab, so das wenn ich auf zeile 2 klicke auch Inhalt 2 auf dem DetailView angezeigt wird. Ich habe auch schon eine Suche implementiert gehabt, die funktionierte aber nicht, da ja jede Zeile ihren festen Wert hat, die sie im DetailView anzeigt. Das heißt ich suche nach "F" dann findet er alle Einträge mit F, ich klicke auf den ersten Eintrag und lande dann auf der DetailView, die zeigt mir dann aber den Wert an den ich ihr zuvor gegeben habe. Ich hoffe ihr versteht :eek:

Wie kann ich also das NSArray so implementieren das ich nicht jeder Zeile den Wert festlegen muss, und eine Suche funktioniert?
 

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
Wenn du eine Suche ohne CoreData implementieren willst, musst du zwei NSArray deklarieren.

Code:
NSArray *dataArray = [[NSArray alloc] initWithObjects:{...}];
NSMutable *filteredArray = [[NSMutableArray alloc] initWithArray:dataArray];

Du füllst den filteredArray erstmal mit allen Einträgen aus dataArray, da das Suchfeld am Anfang noch leer ist -> alle Einträge sind enthalten.

An das Suchfeld hängst du einen Controller an, der alle Änderungen mitkriegt (delegate) und der dann die Einträge im Array auf eine Zeichenfolge absucht. Jede Textänderung handelst du dann etwa so:

Code:
- (void)filterDidChange:(NSString *)searchText {
    [filteredArray removeAllObjects];

    for (NSString *value in dataArray) {
        if ([value rangeOfString:searchText].location != NSNotFound)
             [filteredArray addObject:value];
    }

    [tableView reloadData];
}

So einfach hast du eine Suche für eine TableView.

Du musst dann auch noch die dataSource-Methoden an das filteredArray anpassen.

Gruss ppocket
 
Zuletzt bearbeitet:

branco145

Rheinischer Winterrambour
Registriert
26.07.09
Beiträge
933
Aber dann habe ich ja immer noch das Problem, wenn ich was suche, er z.B "A" findet und ich klicke dann Zeile "A" an dann komme ich auf Beschreibung "B" in der DetailView, weil ich die Zeilen ja fest definiert habe...

Ich muss irgendwie Tabellenzeile "A", Beschreibung "A" auf der DetailView zuweisen ohne das auf eine bestimmte Zeile festzulegen.

Das Video verdeutlicht das nochmal:
http://www.youtube.com/watch?v=fJNs_EsNA7Q&feature=player_embedded

Er nimmt auch in der Suche den festgelegten Eintrag und dann steht halt für "B" in der DetailView "T" statt "B". Er hat also die falsche Beschreibung in der DetailView.
 
Zuletzt bearbeitet:

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
Hier ein Beispielprojekt für die Suche, fertig implementiert. Da ich mich sonst mit UIKit nicht auskenne, weiss ich nicht, wie man diese doofe Tastatur dann wieder wegbringt... das musste selber rausfinden.

Ich hab das so gelöst: Den Text, welcher auf der ModalView angezeigt werden soll, hab ich direkt in die Objekte geschrieben. Du machst also eine neue Klasse mit zwei Properties: Name und Beschreibung.

Dann erstellst du deine Objekte mit dieser Klasse, füllst die Arrays mit diesen Objekten. So kannst du die Beschreibung des angeklicketen Objektes immer ganz einfach über die aktuelle Zeile herausfinden:

Code:
TableEntry *currentEntry = [filteredArray objectAtIndex:inIndexPath.row];

So hast du immer sofort den Namen und die Beschreibung des aktuellen Items. Dies ist alles im Beispielprojekt enthalten. Schau es dir an!

Gruss ppocket

PS: So hast du eine eigene, kleine Datenbank erstellt. Das ist sowieso die Idee, dass du deine Daten speicherst und dann schlau anzeigst. Es ist sehr ineffizient, wie du das gelöst hast. Ich mit meinem Beispiel könnte meine Daten mit meiner Struktur einfach aus einer Datei rauslesen und das am Anfang des Programmes. Dann die Datei links liegen lassen und das Programm einfach machen lassen. Du müsstest jedes Mal wieder auf die Datei zugreifen, da du die Beschreibungen deiner Dienstgrade nirgendwo speicherst, sondern sie statisch im Quellcode selber definierst. Das ist gar nicht die Idee!
 

Anhänge

  • TableSearchExample.zip
    22,3 KB · Aufrufe: 98
Zuletzt bearbeitet:

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
lol... ich setz mich 20 Minuten hinter den Mac und schreibe dir ein Beispielprojekt und du lädst es nicht mal runter. haha, nene, kein Problem! :)
 

branco145

Rheinischer Winterrambour
Registriert
26.07.09
Beiträge
933
Und wie krieg ich es noch hin, das statt des Popups eine neue View angezeigt wird (DetailView)?
 

branco145

Rheinischer Winterrambour
Registriert
26.07.09
Beiträge
933
*push*

Und wie krieg ich es noch hin, das statt des Popups eine neue View angezeigt wird (DetailView)?
 

Zettt

Doppelter Melonenapfel
Registriert
16.10.05
Beiträge
3.374
Scheinbar nicht. Was haeltst du davon wo anders zu fragen?
 

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
Na genau so, wie du es in deinem Code hast!

Gruss ppocket

Sent from my HTC Desire using Tapatalk
 

Drobs

Carola
Registriert
23.05.08
Beiträge
115
Ohne mir das Projekt angeguckt zu haben, gehe ich davon aus, dass Poljpocket einen ModalView benutzt hat.

Das heißt, dass iwo eine Zeile ähnlich dieser steht:

Code:
[self presentModalViewController:MeinUIViewController animated:YES];

welche du, wenn du einen NavigationController hast, durch folgende Zeile ersetzen kannst:

Code:
[self.navigationController pushViewController:MeinUIViewController animated:YES];


Nebenbei würde es sicher helfen, wenn du selber mal dein Hirn anstrengst und dich mit Hilfe von Google auf die Suche nach einer Lösung machst. Das sollte nämlich ohne weiteres möglich sein.
 

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
Er muss nichts mehr überlegen oder suchen. Ich habe nur die dataSource für seine Tabelle verändert und an das Datenmodell angepasst. Er muss in der Methode, wo die Selektion abgefangen wird, nur seinen eigenen Code einfügen und es funktioniert. Ich hab das halt mit einem Alert gelöst, da ich nicht noch extra eine weitere Subklasse erstellen wollte.

Gruss ppocket
 

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
Nein, um das gehts nicht... er hat ja in seinem Code genau (und auch richtig) geschrieben, wie der DetailView Controller angezeigt wird. Er muss diesen Code nur noch kopieren und an mein Datenmodell anpassen. Ganz einfach...

Gruss ppocket
 

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
Hier also nochmal das Beispielprojekt erweitert:

- Anzeige per ModalViewController

Gruss ppocket
 

Anhänge

  • TableSearchExample 2.zip
    29,6 KB · Aufrufe: 62