Massive View Controller - IOS - Lösungen

16

Ich bin mir sicher, dass jeder neue iOS-Entwickler das folgende Problem hat: Die View-Controller sind für verschiedene Zwecke sehr schnell mit Code überfüllt, sodass problemlos mehr als 500 Codezeilen verfügbar sind.

So sieht es bei zwei einfachen und allgemeinen Bildschirmen aus:

1) Der Formularbildschirm: Bildbeschreibung hier eingeben

2) Der Table View Controller-Bildschirm Bildbeschreibung hier eingeben

Bisher habe ich über zwei verschiedene Lösungen gelesen:

  1. Erste Lösung: https://bendyworks.com/single-responsibility-principle-ios/ . Dies basiert auf Benachrichtigungen, trennt den View Controller vollständig vom (Intentions) View Model und reduziert so den Code im View Controller. Ich denke, dass es den Nachteil hat, Code zu brechen, ähnlich wie bei Go-To-Strukturen. Es sieht aus wie das: Bildbeschreibung hier eingeben

  2. Die zweite Lösung behält die gleichen überfüllten View-Controller bei (Schaltflächenaktionen werden in VC usw. ausgeführt). Verwendet jedoch Bibliotheken wie TPKeyboardAvoiding , BlocksKit oder andere Lösungen, die größtenteils auf Kategorien basieren. Mit dieser zweiten Lösung wird der Code drastisch reduziert, aber der Ansichtscontroller hat immer noch viel Verantwortung.

Was halten Sie von diesen Lösungen? Welches ist besser? Gibt es eine bessere?

Ravul
quelle
5
Ich kann aus Zeitgründen keine gute Antwort geben, aber dies sollte Ihnen den Weg weisen.
Mike D
Meine Absicht ist es, so viele gute Antworten wie möglich zu sammeln, um dieses Problem, das so viele neue Entwickler haben, endlich zu überwinden. Danke für den Link, wenn ich etwas Neues finde, werde ich es sicherlich hier posten.
Ravul
Hier ist ein großes Gespräch mit Fett View - Controller von Andy Matuschak über den Kampf gegen https://realm.io/news/andy-matuschak-refactor-mega-controller/
Tomasz Bąk

Antworten:

6

Wir können MVVM verwenden, um dieses Problem zu beheben.

Das Model-View-ViewModel oder MVVM-Muster, wie es allgemein bekannt ist, ist ein Entwurfsmuster für die Benutzeroberfläche. VM übernimmt die gesamte Logik für die Vorbereitung der Modelldaten für die Benutzeroberfläche von VC.

Beispiel:
Sie haben ein Modellobjekt mit einigen Feldern, möchten einige formatieren, berechnen und kombinieren.

Im MVC-Fall befindet sich die gesamte Logik in ViewController.
In MVVM verschieben Sie alles von VC nach VM.

VM bereitet alle Daten für die Benutzeroberfläche vor und VC stellt sie einfach so ein.

(in der VC Klasse)

self.descriptionLabel = self.viewModel.textForDescriptionLabel;

Tutorials und Themen:

Kaspartus
quelle
3
Während dies theoretisch die Frage beantworten mag, wäre es vorzuziehen, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen.
Bart van Ingen Schenau
Ich stimme Bart zu. Wenn sonst niemand eine Zusammenfassung all dieser Methoden veröffentlicht, werde ich eine erstellen, sobald ich sie alle verstehe und teste.
Ravul
2
@Ravul aktualisierte Antwort
Kaspartus
Ich habe Ihre Antwort positiv bewertet und danke Ihnen für diese Idee. Ich lese gerade über funktionale reaktive Programmierung und es scheint eine gute Idee zu sein. Ich denke, die Antwort auf diese Frage ist eine Aufzählung mit ein paar Vor- und Nachteilen und mindestens einem konzeptionellen Diagramm für die folgenden 4 Wege, um das Problem anzugehen: 1) Reaktiver Kakao 2) KVO 3) Delegierte Methode und 4) Klassische Methode von einen View Controller schreiben. Ich werde es schreiben, sobald ich alle diese Methoden ausprobiere, wenn das niemand vor mir tut. Wenn ich inzwischen neue Wege finde, ist das noch besser.
Ravul
3

Ich musste vorher Code in großen View Controllern entwirren, was meine Fähigkeit, durch Inhalte zu navigieren, stark beeinträchtigte. Eine wichtige Erkenntnis war, dass die Größe des View Controllers nicht ausreichte, um die Dinge auseinanderzubrechen. Es ist kompliziert, eine große Datei zu haben, und es ist auch kompliziert, ein paar kleine Dateien zu haben. Hier sind einige gute Gründe für eine Umgestaltung, um einen View Controller in kleinere Teile zu zerlegen:

MVC

Der View Controller sollte nicht viel mehr tun, als das Bindeglied zwischen dem View und dem Model zu sein. Wenn Sie viel Netzwerkverbindungscode, Bildbearbeitungscode usw. haben, sollten Sie diese in Hilfsklassen aufteilen.

Mehrere Steuerelemente mit dem View Controller als Datenquelle

Wenn Sie eine Reihe von Steuerelementen auf dem Bildschirm haben, die Ihren View Controller als Datenquelle haben, sollten Sie diese in separate Datenquellenobjekte aufteilen und als Datenquelle verwenden. Sie können sie auch in separate View-Controller aufteilen (wenn View-Controller neben anderen Controllern über eine Tabellenansicht verfügt, können Sie diese auch in eine eigene Table-View-Controller-Klasse aufteilen).

Doppelter Code

Wenn Sie in verschiedenen View Controllern genau denselben Code haben, geben Sie diesen an einem gemeinsamen Speicherort an. Das macht Ihren Code wiederverwendbar und hilft bei der Verwaltung der Komplexität.

Hier einige zusätzliche Hinweise, um die Komplexität von View Controller zu minimieren:

Storyboard statt programmatisch

Das Erstellen von Ansichtselementen ist viel Code und der Code für die Rahmengeometrie ist ebenfalls viel Arbeit. Wenn nicht bereits erwogen, automatische Layout-Einschränkungen zu verwenden und so viele Ansichtselemente wie möglich in das Storyboard einzufügen.

Unnötiger Code / Kommentare

Achten Sie auch darauf, unnötigen Code / Kommentare zu entfernen. Häufig enthält eine neue View Controller-Datei Methoden, die Sie nicht verwenden. Wenn Sie eine Methode wie didReceiveMemoryWarningdiese nicht verwenden, können Sie sie sicher entfernen. Da die View Controller-Datei manchmal so groß ist, ist es beängstigend, alten Code oder alte Kommentare zu entfernen. Verschiebe das nicht! Dies erhöht nur die Komplexität.

Benachrichtigungen

So beantworten Sie Ihre Frage zu Benachrichtigungen: Benachrichtigungen sind nicht für alle Zwecke geeignet. Ich finde Benachrichtigungen nützlich, wenn aufgrund einer bestimmten Aktion mehrere View Controller gleichzeitig aktualisiert werden müssen. Seien Sie jedoch vorsichtig mit Benachrichtigungen, da eine Überbeanspruchung Ihnen große Schmerzen bereiten kann, wenn Sie versuchen, sie aufzuspüren.

Korey Hinton
quelle
2

Es gibt eine spezielle Architektur, die sie VIPER nennen (View, Interactor, Presenter, Entity und Routing). Ich werde versuchen, hier fortzufahren, was Sie wissen müssen:

Aussicht

  • sie sind Scheinansichten;
  • Enthält Objekte wie UIView, UIViewController, UILabel usw .;
  • wartet auf den Inhalt des Presenters ;
  • Behandeln Sie die Benutzerinteraktion und übergeben Sie sie an die Presenter- Ebene.

Moderator

  • kennt keine UI-Objekte;
  • Eingaben von der Ansichtsebene abrufen;
  • die Ansichtslogik handhaben (die Methode add zeigt einen anderen Bildschirm an);

Routing

  • die Navigationslogik und Übergangsanimationen handhaben;
  • kennt Objekte wie UINavigationController, UIWindow, etc;

Also, was ich denke, dass Sie in Ihrem Code bereinigen werden:

  • Datenüberprüfungen werden auf die Presenter- Ebene verschoben .

  • Die Navigation wird zu Wireframe-Objekten verschoben ( Routing- Ebene).

  • Teilen Sie Ihren View Controller nach dem DRY- Prinzip auf.

  • Komplexe Bildschirme enthalten mindestens zwei Ansichten und Präsentatoren.

Sie sollten den folgenden Link über VIPER-Architektur sehen: http://mutualmobile.github.io/blog/2013/12/04/viper-introduction/

Viel Glück!

orafaelreis
quelle
1
Funktioniert diese Architektur für kleine Anwendungen? Sieht so aus, als müssten Sie viele Objekte erstellen, um sie in das Projekt einzuführen.
Tomasz Bąk
Ja, ich stimme zu, dass es objektiver ist als traditionelles MVC, aber es lohnt sich. Sie können ein einfaches Beispiel sehen, das ich in diesem Jahr erstellt habe. Github.com/orafaelreis/cascavel Cascavel ist wie ein Basisprojekt zum Initialisieren von VIPER-Projekten.
orafaelreis
Ausgezeichnet ! Die VIPER-Architektur scheint genau darauf ausgelegt zu sein, das Problem der massiven View-Controller zu vermeiden.
Christophe