SDK iOS orientation du lecteur iPad

Bienvenue dans le dernier volet de notre série sur la création d’un lecteur iPad pour le La guerre des mondes avec le projet Leaves. Dans le post d'aujourd'hui, je vais démontrer plusieurs techniques qui peuvent être utilisées pour ajuster l'interface lorsque l'orientation de l'appareil change.

Où nous nous sommes laissés?

Il y a environ deux semaines que mon dernier message de cette série a été publié, je vais donc résumer brièvement ce que nous avons couvert jusqu'à présent:

Dans le premier tutoriel de cette série, je vous ai présenté le projet Leaves et expliqué comment l'intégrer à Xcode 4. Ensuite, j'ai montré comment utiliser UISlider avec Leaves pour permettre aux utilisateurs de parcourir rapidement un fichier PDF. Enfin, j'ai montré comment ajouter une table des matières personnalisée pour permettre aux utilisateurs de naviguer entre les chapitres..

Après chacun des postes ci-dessus, j'ai terminé par un sondage et vous ai demandé de voter sur la caractéristique ou le sujet que je devrais aborder ensuite. En réponse au dernier tutoriel, la majorité des répondants souhaitaient voir comment configurer l'interface du lecteur pour les changements d'orientation de périphérique, et c'est ce que je couvrirai aujourd'hui en tant que dernier volet de cette série..

Cependant, avant d’aller plus loin, laissez-moi vous dire ce que ce tutoriel ne fera pas: je n’ajouterai aucune nouvelle fonctionnalité de base au projet Leaves. Vous pouvez réaliser des choses vraiment impressionnantes si vous êtes prêt à vous lancer dans le code de projet principal ou à abandonner vous-même le projet Leaves. J'encourage les personnes impliquées dans la communauté à prendre le relais et à le faire. Malheureusement, il est impossible d’apporter des modifications importantes aux projets principaux de cette série en raison de contraintes de temps. Au lieu de cela, je montrerai simplement comment tirer le meilleur parti de ce que Leaves fournit déjà et comment ajuster les vues personnalisées et les contrôles d'interface créés..

Aperçu du tutoriel

Ceci est une démo vidéo de ce que ce tutoriel va vous apprendre à construire:

Étape 1: Activer le support d'orientation

La première étape pour rendre l’application sensible à l’orientation de l’application consiste à spécifier les orientations WOTWViewController, le contrôleur de vue de projet principal, est capable de supporter. Ceci est fait avec la méthode suivante:

 - (BOOL) devraitAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation // Prend en charge toutes les orientations, renvoie YES; 

le devraitAutorotateToInterfaceOrientation: la méthode est héritée de UIViewController et permet à chaque contrôleur de vue de spécifier les orientations d'interface prises en charge. Pour ce tutoriel, nous voulons tous les aider, alors je retourne simplement "OUI". Cependant, nous pourrions tester des UIInterfaceOrientation valeurs ici en vérifiant la interfaceOrientation paramètre.

Étape 2: Configuration de la restauration automatique des masques

Si vous regardez maintenant notre projet dans le simulateur, vous remarquerez que les choses commencent à changer lorsque l'orientation change, mais vous remarquerez également que ces modifications par défaut laissent beaucoup à désirer. Nous pouvons adopter deux approches fondamentales pour résoudre ce problème. Une approche consisterait à accrocher le UIViewController méthodes qui sont notifiées lorsqu’un changement d’orientation s’est produit, telles que didRotateFromInterfaceOrientation:, et effectuez manuellement les modifications nécessaires à cet endroit. Cependant, une meilleure approche pour notre configuration consiste à configurer simplement le masque de redimensionnement propriété sur nos éléments d'interface pour s'adapter avec souplesse aux changements d'écran automatiquement.

Si vous êtes nouveau dans le masque de redimensionnement propriété, ne vous inquiétez pas. Vous l'avez bien vu dans Interface Builder, où vous pouvez le configurer graphiquement comme ceci:

Ce que vous n'avez peut-être pas compris, c'est que vous pouvez également définir manuellement la propriété dans le code (remarque: en règle générale, si vous pouvez le faire dans Interface Builder, vous pouvez le faire dans le code), ce qui vous permet de contrôler comment les changements d'orientation automatisés auront lieu. Les options d’orientation possibles sont les suivantes:

  • UIViewAutoresizingNone
  • UIViewAutoresizingFlexibleLeftMargin
  • UIViewAutoresizingFlexibleWidth
  • UIViewAutoresizingFlexibleRightMargin
  • UIViewAutoresizingFlexibleTopMargin
  • UIViewAutoresizingFlexibleHeight
  • UIViewAutoresizingFlexibleBottomMargin

Parce que le masque de redimensionnement propriété est un masque de bits entier, vous pouvez combiner plusieurs valeurs en une seule en utilisant simplement l'opérateur OU au niveau du bit pour les combiner.

Par exemple, si je voulais définir myContentView d'avoir tous les UIViewAutoresizing options, je pourrais faire ceci:

 myContentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;

Ou si je voulais myContentView pour ne pas avoir de comportement autoresizing, je pourrais le configurer comme suit:

 myContentView.autoresizingMask = UIViewAutoresizingNone;

Nous allons utiliser cette technique pour configurer le comportement de dimensionnement automatique des objets d'interface suivants: contenuButton, pageSlider, tableOfContentsView, bookHeading, bookOneSubtitle, bookTwoSubtitle, et sectionButton.

Chacune des modifications ci-dessous sera effectuée dans WOTWViewController.m, et le numéro de ligne approprié pour le changement est répertorié avec le code source.

le contenuButton Masque

 contentsButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;

le pageSlider Masque

 self.pageSlider.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

le tableOfContentsView Masque

 tableOfContentsView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;

le bookHeading Masque

 bookHeading.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

le bookOneSubtitle Masque

 bookOneSubtitle.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

le bookTwoSubtitle Masque

 bookTwoSubtitle.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

le sectionButton Masque

 sectionButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
 sectionButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;

Après avoir ajouté toutes les propriétés ci-dessus, enregistrez, générez et exécutez le projet. Vous devriez trouver que la table des matières est BEAUCOUP mieux en orientation paysage maintenant! Cependant, si vous êtes perspicace, vous remarquerez un défaut flagrant: la liste de la table des matières "LIVRE I" est coupée verticalement lorsque vous êtes en mode paysage..

Étape 3: Ajout d'une table des matières UIScrollView

Il existe bien sûr de nombreuses manières de gérer le fait que nous n’avons pas assez d’espace vertical pour afficher la liste de chapitres du LIVRE I. Par exemple, nous pourrions essayer de modifier la hauteur des boutons ou de repositionner la liste de manière à ce qu’elle s’écoule horizontalement au lieu de verticalement. À mon avis, la meilleure expérience utilisateur consiste à utiliser un affichage par défilement pour contrôler la partie de la liste visible..

C'est assez facile à accomplir. Commencez par déclarer un nouveau UIScrollView pour tenir nos boutons de chapitre dans le WOTWViewController.h fichier:

 UIScrollView * sectionScrollView;

Puis initialisez cette variable dans le WOTWViewController.m viewDidLoad méthode et définir le masque de redimensionnement automatique:

 sectionScrollView = [[UIScrollView alloc] initWithFrame: CGRectMake (20.0f, 100.0f, 530.0f, 700.0f)]; sectionScrollView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;

Assurez-vous de le publier plus tard.

Ensuite, réglez le colYOffset et colXOffset variables à 0.0f pour leur valeur initiale, puis mettre à jour le code dans les deux pour boucles pour ajouter le sectionButton objets comme sous-vues de sectionScrollView au lieu de tableOfContentsScrollView:

 [sectionScrollView addSubview: sectionButton];
 [sectionScrollView addSubview: sectionButton];

Puis réglez le contentSize propriété de la vue de défilement:

 sectionScrollView.contentSize = CGSizeMake (523.0f, 680.0f);

le contentSize property contrôle la longueur et la hauteur du contenu défilable et doit être défini pour que cet objet fonctionne correctement. Les valeurs fournies sont A) le décalage X de la deuxième colonne plus 250 (la longueur d'un bouton unique) et B) le décalage de la première colonne y car la première colonne a la plus grande hauteur verticale..

Ajoutez maintenant les lignes de code suivantes:

 sectionScrollView.hidden = YES; [tableOfContentsView addSubview: sectionScrollView];

Ci-dessus, nous ajoutons la vue de défilement à la vue de la table des matières principale, mais comprenez-vous pourquoi nous la cachons d'abord? Rappelez-vous d’un précédent tutoriel de cette série que nous devions activer et désactiver manuellement la table des matières. UIButton objets pour empêcher les touches de vue laisse de déclencher prématurément la sélection de chapitre. Tous les objets de bouton sont maintenant intégrés à la vue de défilement, mais nous souhaitons toujours empêcher la vue de défilement de capturer des événements tactiles non affichés..

Comme il n’est plus nécessaire de basculer manuellement les objets bouton entre les états activé et désactivé, recherchez WOTWViewController.m pour "enabled = YES" et "enabled = NO", et supprimez toutes les lignes responsables du basculement de cette valeur sur les boutons de section, y compris celles du displayTableOfContents et contentsButtonPressed: les méthodes.

Après avoir supprimé les lignes mentionnées ci-dessus, apportez les modifications suivantes pour déclencher le masquage et afficher la vue de défilement à la place:

 - (void) displayTableOfContents // Cache le curseur de page self.pageSlider.hidden = YES; // Affiche la vue de défilement sectionScrollView.hidden = NO; // Animer la transition avec un retournement horizontal de droite à gauche [UIView beginAnimations: nil context: nil]; [UIView setAnimationDuration: 0.5f]; [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView: self-> leaves Cache de cache: OUI]; [self-> leavesView bringSubviewToFront: tableOfContentsView]; [UIView commitAnimations];  - (void) contentsButtonPressed: (UIButton *) sender // Met à jour la position d'affichage du PDF self-> leavesView.currentPageIndex = sender.tag; // Affiche le fichier UISlider self.pageSlider.hidden = NO; self.pageSlider.value = (float) sender.tag; // Animez le fichier PDF jusqu'au sommet des feuillesView Subviews [UIView beginAnimations: nil context: nil]; [UIView setAnimationDuration: 0.5f]; [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView: self-> leavesView cache: YES]; [self-> leavesView sendSubviewToBack: tableOfContentsView]; [UIView commitAnimations]; // Masque la vue de défilement ajoutée à la table des matières lorsqu'elle n'est pas dans la vue sectionScrollView.hidden = YES; 

La vue de défilement doit maintenant être masquée lorsque la vue des feuilles est affichée et affichée lorsque la table des matières est affichée. Enregistrez, générez et exécutez votre projet. Tous nos objets d'interface personnalisés doivent maintenant s'adapter aux changements d'orientation!

Emballer

Mon objectif en écrivant cette série était à la fois de montrer comment ajouter des fonctionnalités utiles à une implémentation par défaut de Leaves, ainsi que de vous enseigner des astuces et des techniques de programmation pour le SDK iOS par des exemples tout au long du processus. J'espère que vous avez appris au moins quelques pépites intéressantes et que cette série vous a été utile dans vos propres projets. N'hésitez pas à laisser un commentaire ci-dessous et à me laisser savoir si cela vous a aidé!

Les solutions actuelles sont-elles suffisantes??

Au cours de cette série, nous avons constaté à la fois des avantages et des inconvénients à l’utilisation du projet Leaves. Personnellement, j'adore la façon dont Leaves peut rapidement vous permettre de créer l'animation de base de boucles page / gauche tout en prenant en charge un certain nombre de formats de contenu différents (y compris le format PDF). Cependant, comme nous l'avons vu au cours de cette série, la mise en œuvre par défaut d'un projet nécessite beaucoup de travail afin de convenir à la plupart des projets professionnels. Nous avons dû contourner le code de projet principal en essayant d'ajouter un curseur et une table des matières, et nous n'avons même pas encore intégré certaines des fonctionnalités les plus complexes mais les plus couramment nécessaires, telles que les surlignages de texte, les signets, les annotations, etc..

Bien entendu, Leaves n'est pas la seule option pour obtenir ce type de fonctionnalité. Dans mon premier article, j'ai mentionné FlipView, HMGLTransitions et le projet PaperStack (toujours inédit au 10/10/2011). Il y a aussi un certain nombre de fourches de projets Leaves et probablement quelques autres projets que je n'ai pas énumérés ici..

Ma question à l’intention de la communauté est la suivante: les options Open Source actuelles pour la création d’applications eReader répondent-elles à vos besoins? Si non pourquoi pas Quelles fonctionnalités aimeriez-vous voir ajoutées aux projets existants qui ne sont pas disponibles actuellement? Soundoff ci-dessous. J'envisage actuellement de rejoindre l'un des projets d'eReader déjà existants ou peut-être même d'en lancer un nouveau, alors j'aimerais connaître vos commentaires.!