Dieses Tutorial ist eine Fortsetzung des Krieg der Welten iPad Reader-Projekt und zeigt, wie Sie mit einem UISlider in einem PDF navigieren, wenn Sie das Leaves-Projekt verwenden. Auf dem Weg dorthin nehmen wir einige ästhetische Änderungen vor, um die Oberfläche ein wenig eindringlicher zu machen.
Im Tutorial der letzten Woche habe ich Ihnen das Open-Source-Projekt Leaves vorgestellt und gezeigt, wie Sie einen einfachen PDF-Reader einrichten. Die grundlegende Leaves-Implementierung ließ jedoch aus Sicht der Benutzererfahrung zu wünschen übrig. Ich habe insbesondere folgende Verbesserungen vorgeschlagen:
60% der Umfrageteilnehmer stimmten für zusätzliche Tutorials zum Hinzufügen eines Inhaltsverzeichnisses oder eines UISliders, sodass wir dies heute erreichen werden. Eine weitere Umfrage wurde in diesen Beitrag aufgenommen. Wenn Sie also zusätzliche Funktionen zu diesem Projekt hinzufügen möchten oder lieber ein anderes iOS SDK-Thema verwenden möchten, lassen Sie es mich wissen!
Dies ist eine Videodemo von dem, was dieses Tutorial erstellt:
Am Ende dieses Tutorials sollten Sie ein gutes Verständnis dafür haben, wie die UISlider
Objektarbeiten und ein besseres Verständnis der internen Informationen des Leaves-Projekts.
Wir werden mit der Vorbereitung der Schnittstelle beginnen, um eine UISlider
. Ich habe hier mit ein paar verschiedenen Ansätzen experimentiert, aber am Ende entschied ich mich für ein Design, das ich nirgendwo anders gesehen habe: Ich habe die Buchanzeige verkleinert, in der Mitte des Bildschirms zentriert und ein paar davon hinzugefügt ferne Galaxie für einen thematischen Effekt. Ich habe dann einfach das zentriert UISlider
unter dem Buch. Ich mag die Art und Weise, wie sich das herausgestellt hat, aber ich gebe gerne zu, dass dies nicht der praktischste Ansatz ist. Wenn Sie eine Reader-Anwendung erstellen, ist es sinnvoll, dass der Text wie in unserem letzten Projektaufbau den gesamten Bildschirm abdeckt. Der Vorteil des Hinzufügens einiger Füllungen um das Buch ist jedoch, dass Sie möglicherweise eine umfassendere Benutzeroberfläche erstellen können. Das ist es, was ich hier versucht habe.
Um das Gleiche zu tun, öffnen Sie die WOTWViewController.xib Datei. Ziehen Sie eine UIImage
auf die iPad-Ansicht und passen Sie das Bild so an, dass es den gesamten Bildschirm ausfüllt (stellen Sie sicher, dass die Ansicht auf den Porträtmodus eingestellt ist). Wählen Sie als Nächstes den Attribut-Inspector für das UIImage
und setze das Bild Feld zu "space.png" (Sie finden diese Datei im Ordner "Resources" des Downloads dieses Beitrags). Wir haben jetzt ein viel cooleres Hintergrundbild für das Projekt. Dies kann sehr leicht für ein anderes Genre als Science Fiction angepasst werden.
Ziehen Sie als nächstes eine UISlider
Objekt auf die Ansicht. Mit dem UISlider
ausgewählt, gehen Sie zum "Größeninspektor". Stellen Sie die Breite des Objekts auf 360, die X-Position auf 204 und die Y-Position auf 955 ein. Der UISlider sollte sich jetzt am unteren Rand des Bildschirms befinden und genau unterhalb der Stelle, an der das Buch angezeigt wird.
An diesem Punkt müssen wir das synchronisieren UISlider
im Interface Builder mit einer Eigenschaft in unserem WOTW-View-Controller. Klicken Sie bei geöffneter XIB-Datei in der Xcode-Symbolleiste auf die Registerkarte Assistent-Editor. Dadurch wird ein Editorfenster geöffnet, in dem das enthalten sein sollte WOTWViewController.h Datei (wenn sie eine andere Datei enthält, wählen Sie die richtige aus dem Symbol "Verwandte Dateien" oben links im Editorfenster). Klicken Sie jetzt auf STRG + UISlider
Ziehen Sie in der XIB-Datei die Linie, die über dem Editorfenster angezeigt wird. Lassen Sie die Taste los, wenn im Pop-Over "Einfügen von Outlets, Aktionen oder Outlet-Sammlungen" angezeigt wird. In einem Dialog werden Sie aufgefordert, einen Namen für die IBOutlet-Verbindung anzugeben. Benennen Sie die Steckdose pageSlider
und klicken Sie auf Verbinden. Der Interface Builder fügt nun den Code hinzu, der für diesen Ausgang in Ihrem Projekt verwendet werden soll.
Wie im ersten Tutorial dieser Serie erwähnt, wird die LeavesViewController
Klasse enthält a UIView
namens LeavesView
wo das Seitenzeichnen tatsächlich stattfindet Der Rahmen von LeavesView
ist so eingestellt, dass die spiegelt LeavesViewController
in dem loadView
Methode, wie unten gezeigt:
LeavesViewController.m
- (void) loadView [super loadView]; leavesView.frame = self.view.bounds; leavesView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.view addSubview: leavesView];
In unserem Fall wollen wir das LeavesView
Rahmen, um nur eine Teilmenge des View-Controllers auszufüllen, nicht den gesamten Bildschirm.
Wir haben hier einige Möglichkeiten. Die einfachste Lösung scheint die Änderung der Größe zu sein LeavesView
Rahmen manuell in Zeile 3 oben im LeavesViewController.m Datei. Sie werden sich jedoch daran erinnern LeavesViewController
ist Teil des offiziellen Leaves-Projektcodes und alle unsere bisherigen Änderungen wurden in vorgenommen WOTWViewController
, das ist eine Unterklasse von LeavesViewController
. Dies ist im Allgemeinen ein viel wartungsfähigerer Ansatz als die Alternative: Hacken Sie im Kernprojektcode nach den für Ihre Situation spezifischen Anforderungen und kämpfen Sie dann kontinuierlich mit Projektaktualisierungen, indem Sie Community-Änderungen wiederholt zusammenführen oder neu schreiben. In einem solchen Szenario werden Sie die neuesten stabilen Builds des Projekts bewusst vernachlässigen. Sie möchten nicht in dieser Situation stecken.
Was ist also eine bessere Alternative? Weil wir das geerbt haben LeavesView
Objekt in WOTWViewController
, Wir können einfach unsere Änderungen in der -(void) viewDidLoad
Methode.
Im WOTWViewController.m, Fügen Sie die folgenden Codezeilen hinzu:
- (void) viewDidLoad [super viewDidLoad]; [self-> leavesView setFrame: CGRectMake (0.0f, 0.0f, 563.0f, 845.0f)]; [self-> leavesView setCenter: self.view.center];
In Zeile 3 oben nennen wir die LeavesViewController
Implementierung von loadView
, und dann passen wir die LeavesView
Rahmen auf eigene Faust. Zeile 4 stellt den Frame auf eine Breite und Höhe ein, die ich für geeignet hielt, und Line 5 zentriert den Frame in der Mitte unseres WOTW-View-Controllers.
HINWEIS: Fragst du dich, warum ich funky-Syntax für den Zugriff auf die LeavesView
Objekt? Dort scheint ein Fehler in GCC 4.2.1 zu sein, der dies erfordert. Kommentare mit weiteren Einsichten sehr geschätzt.
Wenn Sie das Projekt jetzt erstellen und ausführen, sollte der WOTW-Reader in der Mitte des Bildschirms mit einem Schieberegler darunter angezeigt werden. Natürlich funktioniert der Slider noch nicht, also rollen wir weiter!
Wenn unsere Anwendung gestartet wird, möchten wir die minimalen, maximalen und aktuellen Schiebereglerwerte basierend auf der für die App geladenen PDF-Datei festlegen. Wir müssen auch angeben, was passieren soll, wenn sich der Schiebereglerwert ändert. Das machen wir im WOTWViewController.m Datei mit den folgenden Codezeilen:
- (void) viewDidLoad [super viewDidLoad]; [self-> leavesView setFrame: CGRectMake (0.0f, 0.0f, 563.0f, 845.0f)]; [self-> leavesView setCenter: CGPointMake (self.view.center.x, self.view.center.y - 20.0f)]; [self.pageSlider addTarget: Eigenaktion: @selector (turnPageWithSlider :) forControlEvents: UIControlEventValueChanged]; self.pageSlider.minimumValue = 0.0; self.pageSlider.maximumValue = (float) ([self numberOfPagesInLeavesView: self-> leavesView] - 1); self.pageSlider.value = self-> leavesView.currentPageIndex;
Zeile 8 oben legt einen Selektor fest, der aufgerufen werden soll, wenn sich der Schiebereglerwert ändert. Standardmäßig wird der Selektor aufgerufen ständig wenn sich der Slider-Button bewegt. Sie können dies jedoch deaktivieren, indem Sie den Schieberegler einstellen kontinuierlich
Wert auf "NO", wodurch der Wahlschalter erst nach dem Loslassen des Schiebereglers aufgerufen wird.
Zeile 9 oben setzt den Mindestwert auf 0. Dies ist angemessen, da auf die PDF-Datei in Blättern mit einem 0-basierten Index verwiesen wird.
Zeile 10 oben ruft die numberOfPagesInLeavesView:
Methode, um den Maximalwert des Schiebereglers festzulegen, und passt für einen 0-basierten Index an, indem 1 vom Ergebnis abgezogen wird.
Zeile 11 setzt schließlich den aktuellen Wert des Schiebereglers auf LeavesView
Eigentum currentPageIndex
.
Wir schreiben jetzt die Logik, die auftreten soll, wenn die turnPageWithSlider:
Selektor wird aufgerufen.
Fügen Sie der WOTW-Implementierungsdatei den folgenden Code hinzu:
- (void) turnPageWithSlider: (id) sender int pageIndex = (int) [self.pageSlider-Wert]; [self.pageSlider setValue: (float) pageIndex]; self-> leavesView.currentPageIndex = pageIndex;
Der von a zurückgegebene Wert UISlider
ist von der schweben
Datentyp. In Zeile 3 oben typisieren wir diesen Wert in eine Ganzzahl und speichern ihn in der pageIndex
Variable.
In Zeile 4 machen wir das Gegenteil: Wir tippen um pageIndex
zu einem Float und aktualisieren Sie dann den Wert des Schiebereglers. Was ist der Sinn? Ist das nicht überflüssig? Nein, denn wenn wir den Wert des Schiebereglers in eine Ganzzahl typisieren, schneiden wir den Rest ab. Dies ist wichtig, da wir nicht auf Seite 1.23 oder 20.56, sondern auf Seite 1 oder 20 wechseln möchten. Dieser Schritt zwingt den Benutzer, die PDF-Datei in der erwarteten Weise zu durchlaufen.
Zeile 5 oben setzt die LeavesView
Eigentum aktuelle Seite
, Dadurch wird automatisch auch eine Aktualisierung der Buchanzeige erzwungen.
Wenn Sie das Projekt jetzt erstellen und ausführen, sollten Sie in der Lage sein, das Buch zu durchsuchen. Es fehlt jedoch ein wichtiges Detail: Wenn Sie die Seiten durch manuelles Ziehen drehen, bleibt der Wert des Schiebereglers gleich. Hierfür müssen wir den LeavesView-Delegierten aufrufen.
Die benutzerdefinierte Blätteransicht stellt mehrere Delegatmethoden bereit, die an Schlüsselpunkten der Animation aufgerufen werden. Eines davon ist leavesView: didTurnToPageAtIndex:
. Fügen Sie die folgende Logik hinzu, um den Slider zu aktualisieren, wenn diese Delegatmethode aufgerufen wird:
- (void) leavesView: (LeavesView *) leavesView didTurnToPageAtIndex: (NSUInteger) pageIndex if ((int) self.pageSlider.value! = pageIndex) self.pageSlider.value = (float) pageIndex;
Mit dem obigen Code sollte die Implementierung des Sliders abgeschlossen sein!
Wie ich zu Beginn dieses Tutorials erwähnt habe, gibt es noch viele Funktionen, die diesem Projekt hinzugefügt werden können. Wenn Sie diese Serie fortsetzen möchten, stimmen Sie für die Funktion, die Sie als nächstes sehen möchten. Andernfalls können Sie für mich entscheiden, zu einem völlig anderen iOS SDK-Thema überzugehen. Die Umfrage endet am Samstagmorgen, dem 10. September.