• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Was gibt es Schöneres als den Mai draußen in der Natur mit allen Sinnen zu genießen? Lasst uns teilhaben an Euren Erlebnissen und macht mit beim Thema des Monats Da blüht uns was! ---> Klick

Zuerst Login-Form, dann UITabBar

reeng

Granny Smith
Registriert
30.08.10
Beiträge
13
Hallo zusammen

Bei meinem App soll eine UITabBar eingesetzt werden. Allerdings soll beim Starten des App's zuerst eine Login-Form erscheinen, bevor UITabBar geladen wird. Für die verschiedenen View's in UITabBar werden Informationen benötigt, welche in der Login-Form eingegeben werden. Vergleichbar ist dies mit dem Skype-APP ==> Zuerst anmelden, danach erscheinen die persönlichen Daten (Sieht ja beim jedem Login anders aus).
Wie man einen normalen UIViewController erstellt und wie man ein UITabBar erstellt, ist mir klar. Bei beiden Arten wird in der AppDelegate in application DidFinishLaunching... mit [window addSubview: viewController.view]; bzw. [window addSubview: TabBarController.view] die jeweilige Ansicht geladen. Leider jedoch bringe ich es mit meinen bescheidenen Programmier-Kenntnisse nicht hin, dass ich zuerst einen normalen viewController laden kann und erst danach mein UITabBarController. Im "normalen ViewController" hat es zwei Textfelder und einen Button. Beim Klicken auf den Button, soll eben dieser UITabBarController mit den Inhalten der Textfelder als Instanzvariablen geladen werden.
Ich bin bisher wie folgt vorgegangen: In XCode habe ich eine View-based Application erstellt. Dort habe ich meinen "normalen ViewController" mit dem Interface Builder gestaltet (Zwei Textfelder und einen Button). Danach habe ich über New File eine neue UIViewController subClass (namens TabBarController) mit der dazugehörigen .XIB-Datei erstellt. Mit Doppelklick auf dieses XIB-File habe ich im Interface-Bilder dann mein TabBarController erstellt. Ab diesem Schritt habe ich dann nur noch herum probiert und bin nicht annähernd zu einem vernünftigen Resultat gekommen. Ich wäre super froh, wenn mir hier Jemand weiterhelfen könnte. Bin ich überhaupt auf dem richtigen Weg, oder muss ich UITabBar in der AppDelegate erstellen?

Vielen Dank im Vorraus und beste Grüsse aus der Schweiz

reeng
 

JustSid

Granny Smith
Registriert
17.09.10
Beiträge
17
Stichwort: UINavigationController.

Im Prinzip sieht das dann so aus; Du packst den UINavigationController.view auf dein window und setzt als rootviewController den view controller von deiner Login Form. In der login Action (oder wie sie auch immer heißt), erstellst du dann den view controller mit der UITabBar und rufst [self.navigationController pushViewController:animated:] auf. Thats it.
 

reeng

Granny Smith
Registriert
30.08.10
Beiträge
13
Hallo JustSid

Vielen Dank für deine superschnelle Antwort bzw. deinem Tipp mit dem UINavigationController. Ich habe dies mit meiner Login-Form nun umgesetzt. Dies hat auch wunderbar mit einem weiteren UIViewController namens tabBar funktioniert. (Siehe ohne_TabBar.zip)
Danach habe ich im Interface Bilder ein UITabBar Controller im TabBar.XIB hinzugefügt. Nur leider wird mir dieses TabBar nicht angezeigt nach dem Klicken auf den Button (Bei Build and Go). Irgendwie stimmen die Verknüpfungen nicht bzw. ich weiss nicht wie ich diese im Interface Builder richtig setzen kann, habe schon mehrere Möglichkeiten ausgespielt :(. (Siehe mit_TabBar.zip)
Ich hoffe du oder Jemand anders könnte mir nochmals einen hilfreichen Tipp geben, wie ich mein TabBar doch noch angezeigt bekomme. Ich selber denke, dass ich nicht weit davon entfernt bin. Wie bereits erwähnt, habe ich mir erlaubt, mein bisher erstelltes Projekt hier anzugeben. Da mein Projekt über 5MB gross ist, konnte ich es hier nicht anhängen und habe es deshalb auf meinen FTP gelegt. Ich hoffe dies geht in Ordnung.

Beste Grüsse

reeng
 

JustSid

Granny Smith
Registriert
17.09.10
Beiträge
17
Das Problem ist (mit_TabBar.zip) das du keien Instanz des View Controllers erstellst. Das lässt sich ganz einfach beheben in dem du die action so abänderst:
Code:
-(IBAction)weiter:(id)sender
{
	NSLog(@"Button wurde geklickt");
	TabBar *tabBar = [[TabBar alloc] initWithNibName:@"TabBar" bundle:[NSBundle mainBundle]]; // Erstellt eine Instanz von TabBar aus der TabBar.nib.
	[[self navigationController] pushViewController:tabBar animated:YES];
}

Das outlet kannst du dir dann natürlich sparen.

Ein zweites Ding ist das ein UIViewController das view outlet gesetzt haben muss. In der TabBar.xib musst du also noch einen view reintun und das view outlet vom FilesOwner mit dem verknüpfen.
Als nächstes brauchst du dann ein UITabBarController outlet was du mit dem entsprechenden Controller in der .xib verbindest. In der - viewDidLoad fügst du dann self.view den controller.view hinzu um den Inhalt des UITabBarController's zu sehen.

Edit: Hier ist das ganze in funktionierend: http://cl.ly/fab92a0131fff09cbc80 (Musst das BaseSDK zurück auf 4.0 setzen, ich habs bei mir auf 4.2 gesetzt)

Übrigens, ein bisschen Off-Topic, es macht kein Sinn properties zu setzen wenn du sie nie nutzt. In - viewDidUnload solltest du die alle auf NULL setzen und dabei über die getter Methode gehen! Also self.tfEmail = NULL etc. Ansonsten fliegt dir die App irgendwann um die Ohren wenn der stack im UINavigationController wächst und der Speicher nie freigegeben werden kann.
 
Zuletzt bearbeitet:

reeng

Granny Smith
Registriert
30.08.10
Beiträge
13
Wau, das nenne ich hilfsbereit. Tausend Dank. Auf diesem Layout kann ich nun mein Programm aufbauen.
Die Properties werde ich ab jetzt nutzen, um die Strings in die View's von UITabBarController zu übergeben.
In - viewDidUnload solltest du die alle auf NULL setzen und dabei über die getter Methode gehen! Also self.tfEmail = NULL etc. Ansonsten fliegt dir die App irgendwann um die Ohren wenn der stack im UINavigationController wächst und der Speicher nie freigegeben werden kann.
Reicht es nicht aus, wenn ich alle Objekte in der -(void)dealloc Methode wieder entferne? mit pushviewcontroller wird doch ein Release an das Objekt gesendet, welches die Ansicht verliert? (oder ist das nur bei addSubview der Fall)?

Noch eine weitere kleine Wissenslücke würde ich gerne geklärt haben: Im mit_TabBar.zip in der weiter: Methode musste ich ja noch eine Instanz von der Klasse TabBar erzeugen, damit schlussendlich der UITabBarController angezeigt werden kann. In ohne_TabBar.zip habe ich jedoch keine Instanz erzeugt von der Klasse TabBar und dennoch wurde mir der UIViewCOntroller angezeigt?!

Vielen Dank nochmals für deine Unterstützung, so macht das Einsteigen in die iPhone Welt richtig Spass.

Beste Grüsse

reeng
 

JustSid

Granny Smith
Registriert
17.09.10
Beiträge
17
Reicht es nicht aus, wenn ich alle Objekte in der -(void)dealloc Methode wieder entferne? mit pushviewcontroller wird doch ein Release an das Objekt gesendet, welches die Ansicht verliert? (oder ist das nur bei addSubview der Fall)?

Doch doch, in der dealloc Methode solltest du sie natürlich auch releasen. viewDidUnload wird zbsp. aufgerufen wenn du eine memory warning bekommst. Das OS wird als erstes versuchen selber Platz zu schaffen (daemons killen die gerade eh nur idlen, Apps im Hintergrund (iOS >= 4.0) etc). Danach wird es unbenötigtes Zeug von dir entfernen (der UINavigationController braucht ja nicht alles behalten, das wichtige ist das was gerade sichtbar ist. Alles davor kann man ja aus der nib wiederherstellen). Da kannst du nun helfen in dem du outlets freigibst und auf NULL setzt um sie auch als weg zu markieren. Am einfachsten geht das wenn du den setter des Objekts benutzt (natürlich nur solange er auf retain steht!).


Zu der zweiten Sache, das hat aus zwei Gründen funktioniert.
1) In der nib stand bereits drin das der Inhalt von tabBar (deinem outlet) aus der nib "TabBar.xib" geladen werden sollte (das erstellen der Instanz bei dem von mir überarbeitetem Beispiel). Man kann es so oder so machen, das ist mehr so eine persönliche Sache. Ich mag den Interface Builder ehrlich gesagt nicht so und mag deswegen das erzeugen im Code lieber als alles in den nibs zu verknüpfen.

2) Das view outlet in der TabBar.xib war gesetzt. Das ist _ganz_ wichtig! Ein UIViewController bringt von Haus aus das view outlet mit (ist vom Typ UIView). Das _muss_ gesetzt sein, ansonsten gibt es eine exception.
 

reeng

Granny Smith
Registriert
30.08.10
Beiträge
13
Hallo JustSid

Ah, demnach erstellt mir das NIB-File im Hintergrund alle nötigen Instanzen?!
Ich verstehe, warum du den Interface Builder eher meiden möchtest. Mein nächstes Anliegen stützt sich genau auf diese "Unflexibilität" des Interface Builders:
Die weiter: Methode in meiner Login-Form habe ich nun wie folgt mit der setter-Methode ausgebaut:

Code:
-(IBAction)weiter:(id)sender{
	TabBar *tabBar =[[TabBar alloc] initWithNibName:@"TabBar" bundle:[NSBundle mainBundle]];
	tabBar.email = [tfEmail text];
	tabBar.choosenClub = [tfChoosenClub text];
	self.tabBar = tabBar;
	
	[[self navigationController] pushViewController:self.tabBar animated:YES];
}
Bevor mein tabBar also angezeigt wird (pushViewController...), verfügt die Instanz tabBar bereits über die Informationen der Eingegebenen Daten in meinem LoginForm. In tabBar wird ja der UITabBar Controller geladen, welcher mir das Menu für die weiteren ViewControllers bietet (FirstTab, SecondTab etc..). Die Informationen von der Login-Form brauche ich auch in diesen ViewnControllers. In FirstTab.h habe ich die Instanzvariablen email und choosenClub mit den dazugehörigen Properties definiert. Da aber ja nun die Instanz dieser Objekte durch das tabBar.NIB File geregelt wird, kann ich nicht so vorgehen, wie bei meiner weiter: Methode oben. Weist du auch hier ein Rat, damit ich diese Informationen vom Login auf alle ViewControllers übergeben kann? Gibt es eine Möglichkeit im Interface Builder die Instanzvariablen von der Instanz von FirstTab mit den Login-Daten zu füllen, bevor mir das View dieser Instanz angezeigt wird (also analog zu meiner weiter: Methode, einfach im Interface Builder)?

Bedanke mich auch dieses mal bereits im Voraus für deine Bemühungen.

Beste Grüsse

reeng