Benutzerdefinierte Ansichten mit Storyboard

96

In komplexen Bildschirmen (View Controllern) habe ich das Ganze in kleinere Teile geteilt (ich nenne sie Widgets). Diese Widgets bestehen im Wesentlichen aus einer MyWidget.hund einer MyWidget.mDatei sowie einer MyWidget.xibDatei, wobei UIViewdas Stammelement a ist und die MyWidget-Klasse der Dateibesitzer der UIView ist. In der Init dieses Widgets mache ich eine loadNibNamed.

In meinem View Controller mache ich dann eine [[MyWidget alloc] init], die ich als Unteransicht zur Hauptansicht von View Controller hinzufüge. Dies funktioniert bisher perfekt.

Ich frage mich jetzt, wie ich das gleiche mit Storyboard machen soll, weil ich nicht wirklich anfangen kann, UIViewirgendwo etwas hineinzuziehen, ich muss immer mit einem anfangen UIViewController, was ich nicht will.

Wenn dies mit einem Storyboard nicht möglich ist, kann ich es einfach auf die alte Weise tun, indem ich das Storyboard für meine Hauptbildschirme und Segmente verwende und eine separate .xib-Datei verwende, um benutzerdefinierte Ansichten zu definieren?

znq
quelle
Möchten Sie xibs für Ihre View Controller separat und nicht im Storyboard erstellen ?
tipycalFlow
Haben Sie eine Lösung dafür gefunden?
Aryaxt
@aryaxt: Ich verwende eine Mischung aus Storyboard und Xib. Storyboard für die Hauptbildschirme und XIBs mit nur einer UIView als Stamm für komplexe Ansichten oder Widgets. Also nicht wirklich eine Antwort auf meine ursprüngliche Frage (mithilfe des Storyboards), sondern im Grunde das Gleiche wie zuvor.
ZnQ
Verwenden Sie heutzutage nur eine Containeransicht , es ist wirklich so einfach. stackoverflow.com/questions/23399061/…
Fattie

Antworten:

189

Das Einfügen des Widgets / der Ansicht in eine separate .xib-Datei funktioniert und ist insbesondere dann geeignet, wenn Sie dieselbe Ansicht von mehreren Ansichts-Controllern aus referenzieren möchten.

Manchmal möchten Sie jedoch die zusätzliche Ansicht / das zusätzliche Widget im selben Storyboard sehen, und dies ist möglich. So geht's:

  1. Wählen Sie Ihren Ansichts-Controller in IB aus (klicken Sie auf den schwarzen Balken unter der Ansicht) und ziehen Sie eine UIView aus der Objektbibliothek in den schwarzen Balken:

    Geben Sie hier die Bildbeschreibung ein

  2. Wenn sich eine Ansicht in der schwarzen Leiste befindet, wird sie wie jede andere Ansicht in IB instanziiert, jedoch erst dann zu Ihrer Ansichtshierarchie hinzugefügt, wenn Sie dies im Code tun. Ändern Sie die Klasse der Ansicht bei Bedarf entsprechend Ihrer eigenen Unterklasse:

    Geben Sie hier die Bildbeschreibung ein

  3. Sie können es wie jede andere Ansicht an Ihren View Controller anschließen: Geben Sie hier die Bildbeschreibung ein

  4. Die hinzugefügte Ansicht wird in Ihrer Dokumentübersicht angezeigt, und Sie können dort auch Aktionen und Referenzen verknüpfen:

    Geben Sie hier die Bildbeschreibung ein


Das verbleibende Problem besteht nun darin, dass Sie die Ansicht nicht sehen können, egal wie oft Sie versuchen, zu klicken oder zu doppelklicken, was den gesamten Zweck, sie in dasselbe Storyboard zu legen, zunichte machen würde. Glücklicherweise gibt es zwei Problemumgehungen, die mir bekannt sind.

Die erste Problemumgehung besteht darin, die Ansicht von der schwarzen Leiste zurück in die Ansicht Ihres Ansichtscontrollers zu ziehen, sie zu bearbeiten und sie dann wieder in die schwarze Leiste zu ziehen, wenn Sie fertig sind. Dies ist mühsam, aber zuverlässig.

Die andere Problemumgehung ist schwieriger, aber ich bevorzuge sie, weil ich so alle meine Ansichten gleichzeitig sehen kann:

  1. Ziehen Sie eine UITableView aus der Objektbibliothek in Ihre neu hinzugefügte Ansicht.

  2. Ziehen Sie dann eine UITableViewCell in diese UITableView.

    Geben Sie hier die Bildbeschreibung ein

  3. Sobald Sie dies tun, wird Ihre Ansicht auf magische Weise nebeneinander angezeigt, aber Sie haben eine UITableView, die Sie nicht möchten. Sie können die Größe entweder auf 0x0 ändern oder sie löschen, und Ihr UIView bleibt (normalerweise) weiterhin sichtbar.

  4. Gelegentlich wird die sekundäre Ansicht in IB wieder ausgeblendet. Sie können die obigen Schritte wiederholen, wenn Sie die UITableView gelöscht haben oder wenn sich die UITableView noch in der Hierarchie befindet. Klicken Sie einfach auf die UITableViewCell, und die Ansicht wird erneut angezeigt.

Die zweite Methode funktioniert für UIViews, aber nicht so gut für UIToolbars und ist für UIButtons nicht möglich. Die sauberste Lösung, die ich gefunden habe, wenn Sie viele verschiedene Unteransichten einschließen müssen, besteht darin, eine einzelne sekundäre UIView als Container an Ihren View Controller anzuhängen wird nie angezeigt, fügen Sie alle Ihre sekundären Ansichten dort ein und verwenden Sie den UITableViewCell-Trick, um alles sichtbar zu machen. Ich ändere die Größe meines Dummy-UITableView auf 0x0, um dies unsichtbar zu machen. Hier ist ein Screenshot, wie alles zusammen aussieht:

Geben Sie hier die Bildbeschreibung ein

nioq
quelle
März 2013 musste ich das nicht tun - Sie sollten den schwarzen Balken vollständig ignorieren und Ihre Ansicht direkt in die Hauptansicht ziehen / ablegen, und es funktioniert einwandfrei (Xcode 4.5+)
Adam
Ist es möglich, diese benutzerdefinierte Benutzeroberfläche auf demselben ViewController wiederzuverwenden? brauchte zwei benutzerdefinierte uivews - Und wenn es wie ist?
Morten Gustafsson
2
Dang, ich ziehe es vor, nur eine separate xib zu erstellen. Ich werde mich wahrscheinlich nicht an all das erinnern, wenn ich die App in 6 Monaten aktualisieren muss.
Sandy
Obwohl dies eine großartige Antwort ist, habe ich versehentlich einen anderen besseren Weg gefunden, denke ich. Beim Anschließen von Steckdosen an tatsächliche Ansichtskomponenten. Wenn Sie mit der Maus etwas über eine Komponente einer solchen inneren Ansicht fahren, wird diese zur einfacheren Auswahl angezeigt. Dann sehen Sie es auf dem Storyboard ...
Oded Ben Dov
7
Während dies eine unglaublich bewundernswerte historische Antwort ist, ist sie jetzt wirklich völlig veraltet. Apple hat das gesamte Problem behoben, indem "Containeransichten" eingeführt wurden, die jetzt die zentrale und grundlegende Aufgabe beim Erstellen von Apps sind - alles immer eine "Containeransicht". Gott sei Dank, es ist jetzt sehr einfach!
Fattie
11

Wenn Sie Ihre View Controller nur an einen anderen Ort (und nicht in Ihr Storyboard) bringen möchten, gibt es einen ziemlich einfachen Weg, dies zu erreichen:

1) Erstellen Sie Ihre CustomViewControllers ( abcdControllerin dem Code, den ich ausprobiert habe) xibwie gewohnt mit ihren individuellen s.

2) Fügen Sie dem Storyboard eine UIViewController(oder was auch immer Ihre Oberklasse war CustomViewController) hinzu.

3) Setzen Sie die CustomClass auf CustomViewControlleranstatt UIViewControllerwie hier gezeigt:

Geben Sie hier die Bildbeschreibung ein

4) viewDidLoadLaden xibSie abschließend den Benutzerdefinierten und fertig.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSBundle mainBundle] loadNibNamed:@"abcdController" owner:self options:nil];
    // Do any additional setup after loading the view from its nib.
}
tipycalFlow
quelle
3
Vielen Dank für Ihre sehr detaillierte Antwort, aber ich suche eigentlich keinen benutzerdefinierten Ansichts-Controller, sondern eine benutzerdefinierte Ansicht (ein Widget), die einem Standard-UIViewController hinzugefügt wird. Der View Controller ist also nicht das Problem, aber ich habe mich gefragt, wie man am besten benutzerdefinierte Widgets erstellt. Entweder A) mach es wie vorher, mit einer .xib-Datei oder B) einen anderen Ansatz, den ich noch nicht kenne :-)
znq
1
Hmm ... ich glaube ich habe was du willst. Grundsätzlich möchten Sie mehrere Ansichten mit demselben Controller verarbeiten, oder? Ich kann mir keinen anderen Weg als loadNibNamedin diesem Fall
vorstellen
Dies löste dieses Problem für mich: stackoverflow.com/questions/11047991/… Anstelle von viewDidLoad habe ich jedoch loadView verwendet ...
Morkrom
1
Nur um es zu wiederholen, das ist alles (Gott sei Dank!) Völlig veraltet, da die Containeransichten hier sind. Klicken Sie einfach auf eine Containeransicht und alles ist erledigt
Fattie
1

Ich denke, Sie können so etwas tun, um eine Instanz eines bestimmten Viewcontrollers aus dem Storyboard abzurufen und die Ansicht darüber zu verwenden.

ex:
MyViewController* myViewController = [[UIStoryboard storyboardWithName:@"Main"  bundle:nil] instantiateViewControllerWithIdentifier:@"myViewController"];
UIView* view = myViewController.view; //Get the view from your StoryBoard.

Hoffe das hilft

Danke Vijay

vijay_hrd
quelle