Ce tutoriel est une continuation de la La guerre des mondes lecteur iPad et montrera comment naviguer dans un fichier PDF avec UISlider lors de l’utilisation du projet Leaves. En cours de route, nous apporterons quelques modifications esthétiques pour rendre l'interface un peu plus immersive..
Dans le tutoriel de la semaine dernière, je vous ai présenté le projet open source Leaves et expliqué comment installer un lecteur PDF de base. Cependant, l’implémentation de base de Leaves laissait beaucoup à désirer du point de vue de l’expérience utilisateur. Plus précisément, j'ai suggéré les améliorations suivantes:
60% des participants au sondage ont voté en faveur de l'ajout de tutoriels supplémentaires sur l'ajout d'une table des matières ou d'un UISlider. C'est ce que nous allons accomplir aujourd'hui. Un autre sondage a été inclus dans ce message. Si vous souhaitez voir des fonctionnalités supplémentaires ajoutées à ce projet ou si vous préférez que je passe à un autre sujet sur le SDK iOS, faites-le moi savoir.!
Ceci est une démo vidéo de ce que ce tutoriel va créer:
A la fin de ce tutoriel, vous devriez avoir une bonne compréhension de la façon dont le UISlider
objet fonctionne et une meilleure compréhension des internes du projet Leaves.
Nous allons commencer par préparer l’interface pour avoir un UISlider
. J’ai expérimenté différentes approches ici, mais j’ai finalement décidé de choisir un modèle que je n’ai jamais vu ailleurs: j'ai rétréci l'affichage du livre, je l'ai centré au milieu de l'écran, puis j'ai ajouté une toile de fond galaxie lointaine pour un effet thématique. J'ai alors simplement centré le UISlider
sous le livre. En fait, j’aime vraiment la façon dont cela s’est passé, mais j’admets volontiers que ce n’est pas l’approche la plus pratique. Lors de la création d'une application de lecture, il est logique que le texte couvre tout l'écran, comme dans la dernière construction de notre projet, mais le côté positif de l'ajout d'une marge de manœuvre au livre est que vous pouvez potentiellement créer une interface utilisateur plus immersive. C'est ce que j'ai essayé d'accomplir ici.
Pour faire la même chose, ouvrez le WOTWViewController.xib fichier. Faites glisser un UIImage
sur la vue iPad et redimensionnez cette image pour qu'elle remplisse tout l'écran (assurez-vous que la vue est définie sur le mode Portrait). Ensuite, sélectionnez l'inspecteur d'attributs pour le UIImage
et mettre le image field to "space.png" (vous pouvez trouver ce fichier dans le dossier "Ressources" du téléchargement de ce message). Nous avons maintenant une image de fond beaucoup plus froide pour le projet. Cela pourrait très facilement être personnalisé pour un genre autre que la science-fiction.
Ensuite, faites glisser un UISlider
objet sur la vue. Avec le UISlider
sélectionnez "Inspecteur de taille". Définissez la largeur de l'objet sur 360, la position X sur 204 et la position Y sur 955. UISlider doit maintenant être positionné près du bas de l'écran et juste en dessous de l'endroit où le livre sera affiché..
À ce stade, nous devons synchroniser le UISlider
dans Interface Builder avec une propriété dans notre contrôleur de vue WOTW. Le fichier XIB étant toujours ouvert, cliquez sur l'onglet Assistant Editeur de la barre d'outils Xcode. Cela ouvrira une fenêtre de l'éditeur qui devrait contenir le WOTWViewController.h fichier (s'il contient un fichier différent, sélectionnez le fichier approprié dans l'icône "Fichiers associés" en haut à gauche du volet de l'éditeur). Maintenant, CTRL + Cliquez sur le UISlider
dans le fichier XIB et faites glisser la ligne qui apparaît sur le volet de la fenêtre de l'éditeur. Relâchez-le lorsque la fenêtre contextuelle se lit "Insérer une prise, une action ou une collection de prises". Une boîte de dialogue apparaît vous demandant de nommer la connexion IBOutlet. Nommez le point de vente pageSlider
et cliquez sur Connecter. Interface Builder va maintenant ajouter le code nécessaire pour que ce point de vente soit utilisé dans votre projet..
Comme mentionné dans le premier tutoriel de cette série, le LeavesViewController
la classe contient un UIView
appelé feuillesVoir
où le dessin de la page se produit réellement. Le cadre de feuillesVoir
est mis à refléter le LeavesViewController
dans le loadView
méthode, comme indiqué ci-dessous:
LeavesViewController.m
- (void) loadView [super loadView]; leavesView.frame = self.view.bounds; leavesView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [auto.view addSubview: leavesView];
Dans notre cas, nous voulons la feuillesVoir
cadre pour remplir uniquement un sous-ensemble du contrôleur de vue, pas l'écran tout entier.
Nous avons deux options ici. La solution la plus simple semblerait simplement changer la taille de la feuillesVoir
cadre manuellement sur la ligne 3 ci-dessus dans le LeavesViewController.m fichier. Cependant, vous vous souviendrez que LeavesViewController
fait partie du code officiel du projet Leaves et toutes nos modifications ont été apportées jusqu'à présent. WOTWViewController
, qui est une sous-classe de LeavesViewController
. Il s’agit généralement d’une approche beaucoup plus facile à gérer que l’alternative: pirater le code de projet principal pour des besoins spécifiques à votre situation, puis lutter en permanence avec les mises à jour de projet en fusionnant ou en réécrivant de manière répétée les modifications apportées à la communauté. Dans un tel scénario, vous vous retrouverez délibérément à négliger les dernières versions stables du projet.. Vous ne voulez pas vous retrouver coincé dans cette situation.
Alors, quelle est la meilleure alternative? Parce que nous avons hérité du feuillesVoir
objet dans WOTWViewController
, nous pouvons simplement faire nos changements dans le -(void) viewDidLoad
méthode.
Dans WOTWViewController.m, ajoutez les lignes de code suivantes:
- (void) viewDidLoad [super viewDidLoad]; [self-> leavesView setFrame: CGRectMake (0.0f, 0.0f, 563.0f, 845.0f)]; [self-> leavesView setCenter: self.view.center];
Sur la ligne 3 ci-dessus, nous appelons le LeavesViewController
implémentation de loadView
, et ensuite nous personnalisons le feuillesVoir
encadrer nous-mêmes. La ligne 4 définit le cadre sur une largeur et une hauteur que je trouve appropriées et la ligne 5 centre le cadre au milieu de notre contrôleur de vue WOTW..
REMARQUE: Vous vous demandez pourquoi j'utilise une syntaxe géniale pour accéder à la feuillesVoir
objet? Là semble être un bogue dans GCC 4.2.1 qui nécessite cela. Des commentaires plus approfondis très appréciés.
Si vous construisez et exécutez le projet maintenant, vous devriez voir le lecteur WOTW au centre de l'écran avec un curseur sous la navigation. Bien sûr, le curseur ne fonctionne pas encore, alors continuons à rouler!
Lors du lancement de notre application, nous souhaitons définir les valeurs minimale, maximale et actuelle du curseur en fonction du fichier PDF chargé pour l'application. Nous devons également spécifier ce qui doit se passer lorsque la valeur du curseur change. Nous ferons cela dans le WOTWViewController.m fichier avec les lignes de code suivantes:
- (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: auto action: @selector (turnPageWithSlider :) pourControlEvents: UIControlEventValueChanged]; self.pageSlider.minimumValue = 0.0; self.pageSlider.maximumValue = (float) ([self numberOfPagesInLeavesView: self-> leavesView] - 1); self.pageSlider.value = self-> leavesView.currentPageIndex;
La ligne 8 ci-dessus définit un sélecteur qui doit être appelé lorsque la valeur du curseur change. Par défaut, le sélecteur sera appelé continuellement lorsque le bouton du curseur se déplace. Cependant, vous pouvez le désactiver en réglant le curseur continu
valeur sur "NO", ce qui fera que le sélecteur ne sera appelé qu'après le relâchement du bouton de curseur.
La ligne 9 ci-dessus définit la valeur minimale sur 0. Ceci est approprié car le PDF dans Leaves est référencé avec un index basé sur 0.
La ligne 10 ci-dessus appelle le numberOfPagesInLeavesView:
méthode pour définir la valeur maximale du curseur et s'ajuste pour un index basé sur 0 en soustrayant 1 du résultat.
Enfin, la ligne 11 définit la valeur actuelle du curseur sur le feuillesVoir
propriété currentPageIndex
.
Nous allons maintenant écrire la logique qui devrait se produire lorsque le turnPageWithSlider:
le sélecteur s'appelle.
Ajoutez le code suivant dans le fichier d’implémentation de WOTW:
- (void) turnPageWithSlider: (id) expéditeur int pageIndex = (int) [valeur de self.pageSlider]; [self.pageSlider setValue: (float) pageIndex]; self-> leavesView.currentPageIndex = pageIndex;
La valeur renvoyée d'un UISlider
est du flotte
Type de données. Sur la ligne 3 ci-dessus, nous convertissons cette valeur en un entier et la stockons dans le pageIndex
variable.
Sur la ligne 4, nous faisons l'inverse: nous avons transtypé pageIndex
à un float, puis mettez à jour la valeur du curseur. À quoi ça sert? N'est-ce pas redondant? Non, car lorsque nous convertissons la valeur du curseur en entier, nous coupons le reste. Ceci est important car nous ne voulons pas, par exemple, passer à la page 1.23 ou 20.56, mais plutôt à la page 1 ou 20. Cette étape oblige l'utilisateur à parcourir le PDF de la manière attendue..
La ligne 5 ci-dessus définit le feuillesVoir
propriété page actuelle
, ce qui forcera aussi automatiquement une mise à jour de l'affichage du livre.
Si vous générez et exécutez le projet maintenant, vous devriez pouvoir parcourir le livre. Cependant, il manque un détail important: si vous faites pivoter des pages en les faisant glisser manuellement, la valeur du curseur reste la même. Pour cela, nous devons faire appel au délégué LeavesView..
La vue personnalisée Feuilles fournit plusieurs méthodes de délégation appelées à des points clés de l'animation. L'un d'entre eux est leavesView: didTurnToPageAtIndex:
. Ajoutez la logique suivante pour mettre à jour le curseur lorsque cette méthode de délégation est appelée:
- (void) leavesView: (LeavesView *) leavesView didTurnToPageAtIndex: (NSUInteger) pageIndex if ((int) self.pageSlider.value! = pageIndex) self.pageSlider.value = (float) pageIndex;
Avec le code ci-dessus en place, notre implémentation de curseur devrait être complète!
Comme je l'ai mentionné au début de ce didacticiel, de nombreuses fonctionnalités pourraient encore être ajoutées à ce projet. Si vous souhaitez que je continue cette série, votez pour la fonction que vous souhaiteriez voir ci-dessous. Sinon, vous pouvez voter pour moi afin de passer à un sujet complètement différent du SDK iOS (n'hésitez pas à en suggérer un dans la section des commentaires). Le scrutin fermera le samedi matin 10 septembre.