• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung

Anfängerfrage: Application Flow und UI Elemente

style-103

Golden Delicious
Registriert
19.05.08
Beiträge
9
Hallo,

ich beschäftige mich gerade mit der Entwicklung von Iphone apps und habe meine erste TestApp fertig gebaut. Dabei ist mir aufgefallen, dass ich sehr vieles doppelt und dreifach geschrieben habe und ich mehrere views mit dem gleichen Inhalt nutzte.

Kurz gesagt: Ich habe mir jetzt die Basics per learning by doing und google geholt aber mir fehlt noch etwas Grundverständniss für den Aufbau einer app..

Daher wollte ich einfach mal fragen, was der richtige weg ist und Erfahrungen hören.

Das Ziel ist, ein Verzeichnis aufzubauen, das den Benutzer basierend auf Schlagwörter zu einer Detailansicht führt. Sprich, eine klassische Hierarchie wie sie auch im App Store, Mail etc vorkommt.

Das bedeutet ich brauche 2 Views mit jeweils einem Tableview, und 1 DetailView was die Eigenschaft des gesuchtem Produktes anzeigt.

2 Probleme die mir dabei aufgefallen sind:

1) Ich habe also zwei verschiedene Nib Datein erstellt die beide komplett gleich ausgesehen haben.
2) Da mir der TableView nicht gefällt habe ich diesen beidemale in der .m Datei per Quellcode verändert.

Frage
1)
Bei größeren Projekte würde das einen riesen overhead geben, da bei einer kleinen Änderung jedesmal die Dateien doppelt und dreifach geändert werden würden. Da zu dem View ja jedesmal eine .h, .m, nib file gehört und ich dann irgendwann 30-40 Dateien in meinem Projekt habe und nicht mehr durchblicke.

Daher: Gibt es eine Möglichkeit das man einen view zuweist und diesem dann die benötigen Eigenschaften per Property übergibt ? Bzw. Wie sieht ein guter Application Flow aus? Bei den Beispielen die man im Internet findet, werden immer zwei, drei Views benutzt und geben daher kaum Inhalt für ein größeres Projekt.

2) Ich habe drei Tabellen per code verändert. Da sind um die 180 Zeilen nur um die Eigenschaften der Tabelle anzupassen. Diese 180 Zeilen habe ich dann kopiert und in die entsprechende .m für meinen zweiten View kopiert usw. Again: Zu großer overhead bei größeren Projekten, Quellcode wird unleserlich, unflexible bei Veränderungen etc.

Was ist hier die beste Möglichkeit ? Kann ich irgendwie eine Klasse oder ein Controle für meinen UITableView einmalig erstellen, das ich dann immer wieder nutze ?

Ich weiß das sind alles ganz klassische Anfängerfragen und ich sehe Xcode und Objectiv-C wahrscheinlich noch von einem anderen Blickwinkel als wie man ihn sehen sollte. Leider konnte ich bei google nichts entsprechendes finden.

Darum probier ich es hier.

Vielen Dank,
style-103
 

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
Zu deinen beiden Problemen kann ich nur sagen, dass du mit geschickter Einsetzung der Konzepte der objektorientierten Programmierung gleich beide aus der Welt schaffen kannst.

Mach für jedes Layout je eine Controller-Klasse, welche du dann instanzierst und die immer ein- und dasselbe nib ladet. Dann setzt du Properties für Titel, Forward/Back Button (Label, Action, Target) und eine Table Delegate/DataSource. Das gibt dir einmal ein Wenig zu tun, aber dann kannst du ganz einfach mehrere gleiche Views (mit Controller) erstellen, welche individuelle Titel/Inhalte haben.

Resultat:
1 nib
+ 1 controller Klasse
= Reuseability (ein wichtiges Konzept in der OOP)

So, wie du das jetzt machst, würde ich dein Vorhaben nicht angehen.

Gruss ppocket

PS: Falls du das wünschst, kann ich dir ein Beispiel programmieren.
 

reeng

Granny Smith
Registriert
30.08.10
Beiträge
13
Hallo style-103

Ich kann dir zumindest zeigen, wie ich das Problem mit der Detail-Ansicht gelöst habe. Ich verwende nur eine .NIB Datei bzw. einen DetailViewController für alle Tabelleneinträge. Sobald Benutzer selbst Einträge hinzufügen / entfernen können, oder du Tabelleninhalte von einem Server holst, kannst du ohnehin nicht wissen, wie viele DetailViewController du im Vorhinein erstellen musst. Zu meiner Methode: Sobald du ein TableViewController erstellt hast, befindet sich dort die Methode tableView. Dort habe ich folgenden Code platziert:

Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

	NSInteger row = [indexPath row];
	/*if (self.bookDetailViewController != nil){
		[self.bookDetailViewController release];
	}*/
	
	BookDetailViewController *aBookDetail = [[BookDetailViewController alloc] initWithNibName:@"BookDetailViewController" bundle:nil];
	self.bookDetailViewController = aBookDetail;
	[aBookDetail release];
	
	[bookDetailViewController setRowname:[NSString stringWithFormat:@"%@",[booksArray objectAtIndex:row]]];
	bookDetailViewController.title = [NSString stringWithFormat:@"%@",[booksArray objectAtIndex:row]];
	
	NSLog([NSString stringWithFormat:@"%@",[booksArray objectAtIndex:row]]);
	ORBooksAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
	//NSLog([NSString stringWithFormat:@"%@", delegate.choosenClub]);
	[delegate.booksNavController pushViewController:bookDetailViewController animated:YES];
	
	
	
}


Bevor ich die Ansicht vom DetailViewController mit pushViewController lade, habe ich über die Instanz bookDetailViewController die setter-Methode setRowname aufgerufen und dort gleich die ausgewählte Zeile übergeben. In der Klasse von bookDetailViewController muss die setter-Methode natürlich definiert sein. Du könntest es hier auch über die properties lösen. Folgend der Auszug aus meiner DetailViewController Klasse:

Header Datei .h:

Code:
#import <UIKit/UIKit.h>


@interface BookDetailViewController : UIViewController {

	NSString *rowName;
}

-(void) setRowname: (NSString *) arowName;

@end

Detail.ViewCOntroller.m
Code:
#import "BookDetailViewController.h"


@implementation BookDetailViewController

- (void)viewDidLoad {
	
	[super viewDidLoad];
	NSLog(@"%@",rowName); //Manuell ergänzt
	
	UILabel *label = (UILabel *)[self.view viewWithTag:101];
	[label setText: rowName]; 
	
	
}
-(void) setRowname: (NSString *) arowName {
	rowName = [NSString stringWithString: arowName];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}


@end

In diesem DetailViewController hast du nun in der Instanzvariable rowName stets den ausgewählten Tabelleneintrag und kannst deine Elemente anhand dieser Information aufbauen. In diesem Beispiel setze ich den Text eines Labels auf den Namen der ausgewählten Tabellen-Zelle.
Falls es eine elegantatere Art gibt, dies umzusetzen, lasst es mich bitte wissen.

Gruss

renng