Avec ce tutoriel nous apprendrons à programmer une application iOS qui offre à l’utilisateur la possibilité d’habiller sa photo à partir de maquettes de magazines et de pouvoir publier le résultat sur les réseaux sociaux ‘facebook’ et ‘twitter’.
Vidéo du résultat final:
[embedyt]http://www.youtube.com/watch?v=CucHHI7697g[/embedyt]
Note: Le texte en rouge indique une tâche à réaliser en laboratoire.
Action 1 – Créons un nouveau projet de type “Single View” pour le ‘iPad’.
Action 2 – Renseignons les information de création du projet
Action 3 – Ajoutons au projet un ‘groupe’ nommé ‘Mes ressources’.
Action 4 – Ajoutons les trois images précédentes au projet.
Astuce: Il faut enregistrer dans ‘download’ puis, glisser vers le projet.
Action 5 – Plaçons deux contrôles de type ‘UIButton‘ au bas de l’écran et renseignons les propriétés ‘Type‘ et ‘Image‘ pour changer leur apparence.
Action 6 – Glissons ‘ctrl+clic’ le bouton ‘facebook’ vers le le contrôleur de la scène principale.
Action 7 – Renseignons les propriétés du lien du bouton ‘facebook’
Action 8 – Ajoutons le code suivant à la fonction ‘actionFacebook:
@IBAction func actionFacebook(sender: AnyObject) { println("actionFacebook") }
Action 9 – Testons l’app dans le simulateur: Action 10 – Ajoutons une connexion sur le bouton ‘twitter’
// ViewController.swift // TIM-Magazine.swift import UIKit class ViewController: UIViewController { /// Fonction exécutée suite à un clic du bouton 'facebook' @IBAction func actionFacebook(sender: AnyObject) { println("actionFacebook") } // actionFacebook /// Fonction exécutée suite à un clic du bouton 'twitter' @IBAction func actionTwitter(sender: AnyObject) { println("actionFacebook") } // actionTwitter /// Fonction exécutée suite au chargement de la scène en mémoire override func viewDidLoad() { super.viewDidLoad() } // viewDidLoad } // ViewController
Nous allons maintenant ajouter une scène supplémentaire à notre projet.
Action 11 – Ajoutons un nouveau groupe nommé ‘Les couvertures’ au projet.
Action 12 – Dans le groupe ‘Les couvertures’, ajoutons un nouveau fichier.
Explication en classe de la notion de ‘XIB’ vs ‘StoryBoard’
Action 13 – Sélectionnons un fichier de type ‘iOS – User Interface – View’
Action 14 – Nommons la nouvelle scène
Action 15 – Modifions le fond de la scène et ajoutons un titre.
Note: L’ajustement de l’alpha du fond de la scène nous permettra de voir les éléments sous la scène lorsqu’elle sera ajoutée à la scène principale.
Il nous reste maintenant à charger la scène ‘magazine01’ par programmation.
Idéalement, cette scène devrait être affichée au démarrage de l’application.
Rappelle: La scène est une instance de la classe UIViewController.
La classe ‘UIViewController’ contient un membre de type ‘UIView’ qui permet d’afficher des éléments à l’écran.
La classe ‘UIView’ propose la méthode ‘addSubview’ pour ajouter des élements visuels à son canvas d’affichage.
Donc, pour ajouter un élément à la scène principale, il suffit d’appeler la méthode ‘addSubview(un objet visuel)’ du membre ‘view’ de l’instance de la classe de la scène.
Par exemple, pour ajouter un ‘UILabel’ à l’écran il suffit de programmer: view.addSubView(UILabel()).
Note: « self.view » est valide aussi.
Action 16 – Ajoutons le code suivant à la méthode ‘viewDidLoad’ du contrôleur de la scène principale.
override func viewDidLoad() { super.viewDidLoad() // Début de notre code... // Créer la vue de 'Magazine01' par prog var ecranMagazine = UINib(nibName: "Magazine01", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UIView // Ajouter la nouvelle ‘View’ à la scène principale view.addSubview(ecranMagazine); } //viewDidLoad
Action 17 – Exécutons le projet dans le simulateur
Solution: Insérer la maquette avant les boutons.
Action 18 – Observons la structure des éléments de la scène
Action 19 – Modifions le code, pour ajouter le magazine avant les boutons ‘facebook’ et ‘twitter’
// Insérer la nouvelle ‘View’ avant les boutons fb et twitter println("view.subviews.count: \(view.subviews.count)") view.insertSubview(ecranMagazine, atIndex: (view.subviews.count - 2) - 1 ) // Ou bien ceci pour ajouter au haut de la liste view.insertSubview(ecranMagazine, atIndex: 0)
Action 20 – Exécutons le projet dans le simulateur
L’approche précédente pose un problème, il faudra modifier l’indice d’insertion à chaque fois que nous ajouterons des éléments de contrôle à la scène principale.
Par exemple, un menu pour changer de magazine.
Il est possible de regrouper des objets visuels ensemble grâce à l’objet ‘UIView’.
Action 21 – Ajoutons un objet ‘UIView’ à la scène principale.
Action 22 – Remplaçons la valeur de paramètre ‘atIndex’ pour ‘view.subviews.count – 1″
Action 23 – Renseignons le fond de la scène principale à « noir » et le fond de la maquette ‘Magazine01′ à « Clear color’ (transparent).
Action 24 – Testons avec le simulateur:
Réflexion: Nous assumons que la ‘view’ du fichier XIB sera toujours à la position [0] du XIB. Si Apple change la position de la ‘view’, notre programme ne fonctionnera plus correctemnt.
La méthode recommandée par Apple pour charger la ‘view’ du fichier XIB est la suivante:
var ecranMagazine = UIView() // Parcourir tous les éléments du fichier for x in UINib(nibName: "magazine01", bundle: nil).instantiateWithOwner(nil, options: nil) { // si objet courant de type 'UIView' alors renseigner notre variable if x.isKindOfClass(UIView) { ecranMagazine = x as! UIView } // if } // for
Téléchargement du projet à cette étape.
Action 25 – Vous devez réaliser les maquettes suivantes:
Note: Pendant l’étape d’élaboration des maquettes, il est recommandé de fixer la couleur de la scène à noir. Cela va permettre de distinguer le texte blanc. Nous changerons le fond de ‘noir’ à ‘transparent : clearcolor’ à l’étape de chargement des interfaces.
Astuce: Pensez à copier/coller le fichier Magazine01.xib vers 02..04.xib.
Action 26 – Ajoutons un ‘UISegmentedControl’ dans la section interactive.
Résultat final:
Définissons un lien IBAction sur le ‘UISegmentedControl’
/// Fonction exécutée suite à une sélection dans le 'UISegmentedControl'. Note: Doit-être liée au UISC. @IBAction func actionTournerPages(sender: AnyObject) { let selection = (sender as! UISegmentedControl).selectedSegmentIndex println("actionTournerPages: la sélection vaut: \(selection)") }
@IBAction func actionTournerPages(sender: AnyObject) { // 1 - Retirer le magazine courant de la scène // 2 - Construire une chaine de caractères qui décrit le nom du fichier: 'Magazine0' + selectionCourante + 1 // 3 - Charger le magazine à partir d’un nom d’un fichier NIB // 4 - Ajouter le magazine à la scène principale }
PRÉ-REQUIS – Configuration des comptes sociaux sur l’appareil iOS.
Note: Au moment d’écrire cet exercice, le social.FrameWork n’était pas encore disponible dans la librairie iOS version 8. Assurez-vous de renseigner le version 7.x dans le paramètre de déploiement du projet.
Capture d’une Vue vers un objet UIImage
func sauvegarderEcran(){ // Description : méthode servant à capturer l’écran et au besoin, // en faire une sauvegarde dans l’album photos. // 1 - Préparer un contexte de dessin à partir de la taille de la scène UIGraphicsBeginImageContext(self.view.bounds.size); // 2 – Dessiner à partir du claque par défaut de la scène self.view.layer.renderInContext(UIGraphicsGetCurrentContext()); // 3 – Stocker le résultat dans notre objet local imageFinale = UIGraphicsGetImageFromCurrentImageContext(); // 5 – Fermer le contexte de dessin UIGraphicsEndImageContext(); // 6 – Facultatif - Stocker une copie de la capture d’écran dans l’album photos UIImageWriteToSavedPhotosAlbum(imageFinale, nil, nil, nil ); } // sauvegarderEcran
Vérifions la présence de la capture dans l’album de photos.
Envoyer un ‘post’ vers Facebook
import Social func posterSurFacebook() { // Les étapes pour utiliser ‘facebook’ // 1 - Tester si le service et les informations de connexion sont dispo if SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook) { // 2 - Créer un feuille pour le 'post' let controleur = SLComposeViewController (forServiceType: SLServiceTypeFacebook) // 3 - Composer le message controleur.setInitialText("Test avec Swift et Xcode"); // 4 - Ajouter une image - facultatif controleur.addImage(imageFinale); // 5 - Ajouter un lien - facultatif controleur.addURL(NSURL(fileURLWithPath:"/cours/xcode/")); // 6 - Présenter la fenêtre de confirmation à l'utilisateur self.presentViewController(controleur, animated: true, completion: nil); } // if Facebook } // posterSurFacebook
Modifions la méthode ‘actionFacebook’.
@IBAction func actionFacebook(sender: AnyObject) { println("actionFacebook") sauvegarderEcran() posterSurFacebook() } // actionFacebook
Action – Testons l’application
Action – Modifiez le méthode actionTwitter
Il reste à cacher la zone menu avant de capturer l’écran.
Définissons un IBOutlet sur la View du menu.
Ajoutons le code suivant à la méthode capturerEcran.
func sauvegarderEcran(){ // Cacher le menu leMenu.hidden = true // 1 ... // 6 leMenu.hidden = false } // sauvegarderEcran
Note: Cette étape est facultative. Il n’y aura pas d’explication en classe, Si vous la réalisez, la correction du projet se fera sur 12/10.
Le contrôle ‘UIScrollView’ permet d’afficher un contenu plus grand que sa zone d’affichage.
Une gestuelle sur l’écran donne accès au contenu non visible.
Méthode d’utilisation du contrôle:
1 – Placer le ‘UIScrollView’ sur une scène,
2 – Par programmation, ajouter des objets dans le ‘UIScrollView’ en renseignant correctement les positions x/y,
3 – Renseigner la propriété ‘UIScrollView’.contentSize
func chargerLesMagazines() { // Renseigner la largeur de la zone de contenu du scrollView en fn du nb de pages. let pagesScrollViewSize = zoneAffichageDesElements.frame.size zoneAffichageDesElements.contentSize = CGSizeMake(pagesScrollViewSize.width * Float(nbMagazines), pagesScrollViewSize.height) for page in 0..<nbMagazines { // Placer les Views un à la suite de l'autre sur le plan des 'x' var frame:CGRect = zoneAffichageDesElements.bounds frame.origin.x = frame.size.width * Float(page) // la première page (0) sera à x = 0 frame.origin.y = 0 // Charger le 'xib' courant var nomNIB = "Magazine0\(page+1)" println(nomNIB) if var newPageView = UINib(nibName: nomNIB, bundle: nil).instantiateWithOwner(nil, options: nil)[0] as? UIView { newPageView.frame = frame; // Ajouter au scrollView zoneAffichageDesElements.addSubview(newPageView) } // if newPageView } // for page } // chargerLesMagazines()
Testons
Activons le ‘paging enable’
Ajoutons un UIPageControl (indicateur de la page courante/nbPages)
Expliquer Délégation
// Une des Méthodes de délégation de UIScrollView func scrollViewDidEndDecelerating(scrollView: UIScrollView){ println("scrollViewDidEndDecelerating") let positionPage = Int(zoneAffichageDesElements.contentOffset.x / zoneAffichageDesElements.frame.size.width) indicateurDePages.currentPage = positionPage } // scrollViewDidEndDecelerating
Remplaçons le code de la méthode ‘viewDidLoad.
override func viewDidLoad() { super.viewDidLoad() // Début de notre code... // L'ancien code de chargement du magazine01 doit-être supprimé. chargerLesMagazines() } // viewDidLoad
FIN du laboratoire