Eine der Änderungen, die mit iOS 6 eingeführt wurden, ist die Möglichkeit, den UIPageViewController für die Verwendung einer Bildlaufanimation anstelle des standardmäßigen Seitenwechselstils zu verwenden. Lesen Sie weiter, um zu erfahren, wie wir auf diese Weise einen paginierten Bildlaufeffekt erzeugen können!
Um diese Änderungen zu untersuchen, erstellen wir eine "Image Rater" -Anwendung, in der Benutzer verschiedene Bilder durchblättern und jedem Bild eine Bewertung geben können. Obwohl die Prämisse grundlegend ist, haben Sie eine gute Chance, UIPageControl mit dem neuen Stil zu verwenden.
Bevor wir anfangen, brauchen wir ein paar Bilder. Springe in Wikipedia und lade 5 verschiedene Bilder herunter, die unter einer Creative Commons-Lizenz stehen. Erstellen Sie ein neues Xcode-Projekt mit einer leeren Vorlage. Nennen Sie es "ImageRater" oder etwas Äquivalentes. Stellen Sie außerdem sicher, dass das Zielgerät auf iPad eingestellt ist, das Storybording deaktiviert ist und ARC aktiviert ist.
Dieses Projekt wird nur für die Landschaftsorientierung konzipiert. Bevor Sie beginnen, öffnen Sie die Projekteinstellungen und wählen Sie nur die Landschaftsausrichtungen aus.
Als Nächstes müssen Sie das Modellobjekt und den View-Controller erstellen, die für die Anzeige des Bildes verantwortlich sind. Erstellen Sie eine neue Klasse mit dem Namen "ImageModel", die von NSObject erbt. Dies wird eine einfache Modellklasse sein, die eine Zeichenfolge enthält, die den Namen der Bilddatei darstellt, und eine Ganzzahl, die die "Bewertung" des Bildes darstellt:
ImageModel.h
@ Schnittstelle ImageModel: NSObject - (id) initWithImageName: (NSString *) imageName; @ property (nichtatomisch, stark) NSString * imageName; @ property (nonatomic) NSInteger-Bewertung; @Ende
Wir haben auch eine benutzerdefinierte Init-Methode erstellt, die das Erstellen dieser Bilder mit einem Bildnamen vereinfacht. In der .m-Datei implementieren Sie die init-Methode folgendermaßen:
ImageModel.m
@implementation ImageModel - (id) initWithImageName: (NSString *) imageName self = [Super-Init]; if (selbst) _imageName = imageName; _bewertung = 0; return self;
Der View-Controller, der das Bild anzeigt, ist ebenfalls sehr einfach. Erstellen Sie eine neue Klasse namens ImageViewController (UIViewController) und geben Sie die folgenden Eigenschaften an (und importieren Sie ImageModel.h):
ImageViewController.h
#import "ImageModel.h" @interface ImageViewController: UIViewController @property (nicht atomar, stark) UIImageView * imageView; @ property (nichtatomisch, stark) UILabel * Label; @ property (nonatomic, strong) ImageModel * -Modell; @Ende
Fügen Sie in der M-Datei den folgenden Code hinzu:
ImageViewController.m
- (void) viewDidLoad [super viewDidLoad]; [self.view setBackgroundColor: [UIColor whiteColor]]; CGRect insetFrame = CGRectMake (20, 80, self.view.frame.size.width - 40, self.view.frame.size.height - 100 -); _imageView = [[UIImageView-Zuordnung] initWithFrame: insetFrame]; _imageView.backgroundColor = [UIColor clearColor]; [_imageView setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; [_imageView setImage: [UIImage imageNamed: _model.imageName]]; [[self view] addSubview: _imageView];
Wenn die Ansicht geladen wird, legen wir die Hintergrundfarbe der Ansichten fest und richten die imageView ein.
Erstellen Sie eine neue Klasse namens "RootViewController" (erbt von UIViewController). Hier wird die Aktion ausgeführt. Es enthält den PageViewController, die Bezeichnung, die den Namen und die Rangfolge des Bildes angibt, sowie einen Stepper, mit dem der Benutzer die Bewertung für das Bild festlegen kann.
Nachdem Sie die Klasse erstellt haben, öffnen Sie die Header-Datei der Delegaten der App, importieren Sie die RootViewController-Klasse und legen Sie sie als Eigenschaft fest:
AppDelegate.h
#import "RootViewController.h" @interface AppDelegate: UIResponder@ property (strong, nonatomic) UIWindow * -Fenster; @ property (strong, nonatomic) RootViewController * viewController; @Ende
Und in der Implementierungsdatei setzen Sie es als Root-View-Controller:
AppDelegate.m
- (BOOL) -Anwendung: (UIApplication *) -Anwendung didFinishLaunchingWithOptions: (NSDictionary *) launchOptions self.window = [[UIWindow-Zuordnung] initWithFrame: [[UIScreen mainScreen] bounds]]; // Überschreibungspunkt für die Anpassung nach dem Anwendungsstart. self.viewController = [[RootViewController-Zuordnung] init]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; JA zurückgeben;
Öffnen Sie die .h-Datei des RootViewControllers, und geben Sie die folgenden Eigenschaften an, und passen Sie sie den UIPageViewControllerDataSource- und Delegate-Methoden an:
RootViewController.h
@interface RootViewController: UIViewController@ property (nicht atomar, stark) UIPageViewController * pageViewController; @ property (nichtatomisch, stark) NSMutableArray * modelArray; @ property (nonatomic) NSInteger vcIndex; @ property (nichtatomisch, stark) UIStepper * rateStepper; @ property (nichtatomisch, stark) UILabel * imageLabel; - (void) stepperValueChanged: (id) Absender; @Ende
Der pageViewController ist für die Anzeige der ImageViewControllers und das Modell-Array für das Speichern der imageModel-Objekte verantwortlich. Der vcIndex ist dafür verantwortlich, den aktuellen Seitenindex zu verfolgen. RateStepper ermöglicht es dem Benutzer, ein Bild nach oben oder unten zu bewerten. Das imageLabel zeigt den Namen und die Bewertung des aktuellen Bildes an.
Die stepperValueChanged-Methode aktualisiert das relevante Bildmodell und setzt seine Bewertung nach oben oder unten.
Importieren Sie in der .m-Datei des RootViewControllers den ImageViewController und richten Sie die View-Controller für den Page-View-Controller ein:
RootViewController.m
#import "ImageViewController.h" @implementation RootViewController - (void) viewDidLoad [super viewDidLoad]; [[Selbstansicht] setBackgroundColor: [UIColor blackColor]]; _modelArray = [NSMutableArray arrayWithObjects: [[ImageModel-Zuordnung] initWithImageName: @ "cat.jpg"], [[ImageModel-Zuordnung] initWithImageName: @ "DawnFlight.jpeg"], [[ImageModel-Zuordnung] initWithImageName: @ "James.jpg] , [[ImageModel-Zuordnung] initWithImageName: @ "MOS_KIM.jpg"], [[ImageModel-Zuordnung] initWithImageName: @ "Pterophorus.jpg"], nil]; _pageViewController = [[UIPageViewController-Zuordnung] initWithTransitionStyle: UIPageViewControllerTransitionStyleScroll navigationOrientation: UIPageViewControllerNavigationOrientationHorizontal-Optionen: [NSDictionary dictionaryWithObject: [NSNumber numberWithFloat: 50.0f] forKey: UIPageAdrinkontorkontaktKontaktKontaktKontakt _pageViewController.delegate = self; _pageViewController.dataSource = self;
Hier ist einiges los. Zuerst setzen wir unsere Hintergrundfarbe auf Schwarz. Zweitens weisen wir init unseren pageViewController mit dem Übergang scollStyle, der horizontalen Navigationsausrichtung und einem Wörterbuch für unsere Optionen zu. Das Wörterbuch enthält eine NSNumber, die angibt, dass zwischen jedem viewController ein Abstand von 50 Punkten bestehen sollte. Anschließend setzen wir uns als Delegat und Datenquelle für den PageViewController fest.
Als Nächstes müssen wir einen ersten viewController einrichten, um mit zu beginnen:
RootViewController.m
_pageViewController.delegate = self; _pageViewController.dataSource = self; ImageViewController * imageViewController = [[ImageViewController-Zuordnung] init]; imageViewController.model = [_modelArray objectAtIndex: 0]; NSArray * viewControllers = [NSArray arrayWithObject: imageViewController]; [self.pageViewController setViewControllers: viewControllers Richtung: UIPageViewControllerNavigationDirectionForward animiert: NEIN Completion: nil]; [self addChildViewController: _pageViewController]; [self.view addSubview: _pageViewController.view]; [_pageViewController didMoveToParentViewController: self]; CGRect pageViewRect = self.view.bounds; pageViewRect = CGRectInset (pageViewRect, 40.0, 80.0f); self.pageViewController.view.frame = pageViewRect; self.view.gestureRecognizers = _pageViewController.gestureRecognizers;
Hier erstellen wir einen neuen Content-View-Controller, fügen ihn einem Array hinzu und legen dieses Array dann als viewControllers -Eigenschaft für unseren pageController fest. Als nächstes fügen wir den pageViewController als unseren childViewController und dann den pageViewControllersView zu unserem eigenen hinzu. Wir geben ihm dann eine kleine Einfügung, damit er nicht die gesamte Ansicht einnimmt, und setzen unsere Gestenerkenner auf die des pageViewControllers, sodass alles synchron ist.
Zum Abschluss der Ansicht müssen Sie den Stepper und das Label hinzufügen, die das Bild beschreiben:
RootViewController.m
self.view.gestureRecognizers = _pageViewController.gestureRecognizers; _rateStepper = [[UIStepper-Zuordnung] initWithFrame: CGRectMake (40, 680, 40, 30)]; [_rateStepper addTarget: Eigenaktion: @selector (stepperValueChanged :) forControlEvents: UIControlEventValueChanged]; [_rateStepper setMinimumValue: 0]; [_rateStepper setMaximumValue: 10]; [_rateStepper setIncrementImage: [UIImage imageNamed: @ "arrowup"] forState: UIControlStateNormal]; [_rateStepper setDecrementImage: [UIImage imageNamed: @ "arrowdown"] forState: UIControlStateNormal]; [[self view] addSubview: _rateStepper]; _imageLabel = [[UILabel-Zuordnung] initWithFrame: CGRectMake (0, 0, self.view.frame.size.width, 40)]; _imageLabel.backgroundColor = [UIColor clearColor]; _imageLabel.textColor = [UIColor whiteColor]; [_imageLabel setFont: [UIFont boldSystemFontOfSize: 20]]; [_imageLabel setAutoresizingMask: UIViewAutoresizingFlexibleWidth]; [_imageLabel setTextAlignment: NSTextAlignmentCenter]; ImageModel * model = [_modelArray objectAtIndex: 0]; _imageLabel.text = [NSString stringWithFormat: @ "% @ - Bewertung:% d", model.imageName, model.rating]; [[self view] addSubview: _imageLabel];
Das meiste davon sollte ziemlich unkompliziert sein. Die Hauptsache, auf die wir hier achten müssen, ist, wo wir die "Inkrement" - und "Dekrement" -Bilder für die Schrittsteuerung einstellen. Sie müssen dafür Ihre eigenen Bilder finden, aber es sollte einfach sein, einige kostenlose Icons bei Google zu erstellen oder zu finden. Wenn Sie dies nicht tun können, können Sie das Anpassen des Steppers einfach überspringen.
Wenn wir unsere App jetzt erstellen und ausführen, sollte sie ungefähr so aussehen:
Dies ist ein guter Anfang, aber die Bilder scrollen noch nicht und der Stepper stürzt die App ab. Wir vermissen auch die Seitenindikatoren. Füllen Sie diese Felder aus:
Wir müssen die Datenquellenmethoden implementieren, die dem pageViewController mitteilen, welche View-Controller vor und nach dem aktuellen Controller geladen werden sollen:
RootViewController.m
#pragma mark - #pragma mark - UIPageViewControllerDelegate-Methode - (UIViewController *) pageViewController: (UIPageViewController *) pageViewController viewControllerBeforeViewController: (UIViewController *) viewController NSUInteger currentIndex = [_modelArray indexOfObject: [contentVc-Modell]]; _vcIndex = currentIndex; [_rateStepper setValue: [[Bewertung von contentVc-Modell]]]; ImageModel * model = [_modelArray objectAtIndex: _vcIndex]; [_imageLabel setText: [NSString stringWithFormat: @ "% @ - Bewertung:% d", model.imageName, model.rating]]; if (currentIndex == 0) return nil; ImageViewController * imageViewController = [[ImageViewController-Zuordnung] init]; imageViewController.model = [_modelArray objectAtIndex: currentIndex - 1]; return imageViewController; - (UIViewController *) pageViewController: (UIPageViewController *) pageViewController viewControllerAfterViewController: (UIViewController *) viewController ImageViewController * contentVc = (ImageViewController *) viewController; NSUInteger currentIndex = [_modelArray indexOfObject: [contentVc-Modell]]; _vcIndex = currentIndex; [_rateStepper setValue: [[Bewertung von contentVc-Modell]]]; ImageModel * model = [_modelArray objectAtIndex: _vcIndex]; [_imageLabel setText: [NSString stringWithFormat: @ "% @ - Bewertung:% d", model.imageName, model.rating]]; if (currentIndex == _modelArray.count - 1) return nil; ImageViewController * imageViewController = [[ImageViewController-Zuordnung] init]; imageViewController.model = [_modelArray objectAtIndex: currentIndex + 1]; return imageViewController;
Beide Methoden sind sehr ähnlich. Zuerst bekommen wir den relevanten viewController vor oder nach dem aktuellen (und setzen ihn in einen ImageViewController um). Wir suchen dann, wo sich der Index des ViewController-Modells in Relation zu unserem Modellarray befindet. Sobald wir ihn gefunden haben, setzen wir unseren aktuellen vcIndex-Wert auf den currentIndex. Wir stellen außerdem sicher, dass Sie den aktuellen Wert des Steppers und die Beschriftungszeichenfolge aktualisieren, um den aktuellen Bildnamen und den Bewertungswert anzuzeigen.
Wenn der Index außerhalb des zulässigen Bereichs liegt (bestimmt durch 0 oder die Anzahl des Modell-Arrays - 1), wird kein neuer View-Controller zurückgegeben. Wenn ein Modell geladen werden soll, erstellen wir einen neuen ImageViewController, setzen ihn auf das entsprechende Modell im Array und geben den viewController zurück.
Wenn Sie jetzt bauen und ausführen, werden die Seiten gescrollt. Die Seitenindikatoransicht fehlt jedoch noch. Wir müssen nur die folgenden dataSource-Methoden wie folgt implementieren:
RootViewController.m
#pragma mark - #pragma mark - UIPageViewControllerDataSource-Methode - (NSInteger) presentationCountForPageViewController: (UIPageViewController *) pageViewController return _modelArray.count; - (NSInteger) presentationIndexForPageViewController: (UIPageViewController *) pageViewController return 0;
So einfach ist das. Für die count-Methode geben wir einfach die Anzahl des Modell-Arrays zurück, und für den aktuellen Index geben wir einfach das zurück, was zum Start benötigt wird, nämlich 0.
Alle harte Arbeit wurde erledigt! Um die Bilder zu ordnen, implementieren Sie einfach unsere Methode "stepperValueChanged" und fügen Sie den folgenden Code hinzu:
RootViewController.m
#pragma mark - #pragma mark - Private Methods - (void) stepperValueChanged: (id) sender ImageModel * model = [_modelArray objectAtIndex: _vcIndex]; [model setRating: [_ rateStepper value]]; [_imageLabel setText: [NSString stringWithFormat: @ "% @ - Bewertung:% d", model.imageName, model.rating]];
Wir erhalten das Modell einfach am aktuellen Index, aktualisieren seine Bewertung basierend auf der Bewertung der Stepper und aktualisieren dann den Etikettentext.
Erstellen und starten Sie Ihre Anwendung jetzt und sie sollte in etwa wie folgt aussehen:
Wir haben beschrieben, wie Sie einen sehr einfachen PageViewController mit dem neuen Bildlaufübergangsstil einrichten, ohne Xib oder Storyboard zu verwenden. Dies sollte Ihnen ein solides Verständnis der Funktionsweise von PageViewController vermitteln und Sie können es so anpassen, dass es in Ihren eigenen Anwendungen funktioniert!