{"id":2751,"date":"2016-08-17T09:10:27","date_gmt":"2016-08-17T13:10:27","guid":{"rendered":"\/cours\/xcode\/wp\/?page_id=2751"},"modified":"2021-04-29T20:14:50","modified_gmt":"2021-04-29T20:14:50","slug":"tim-magazine-swift3","status":"publish","type":"page","link":"https:\/\/ve2cuy.com\/xcode\/tim-magazine-swift3\/","title":{"rendered":"TIM-Magazine.swift3"},"content":{"rendered":"<p><strong><span style=\"color: #ff0000;\">Note<\/span><\/strong>: <span style=\"color: #ff0000;\"><strong>Sous Xcode 9, il faut choisir un &lsquo;deployment target&rsquo; inf\u00e9rieure \u00e0 iOS 11.0. \u00a0Au besoin, installer un simulateur roulant la version 10.3 de iOS.\u00a0<\/strong><\/span><br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2016\/08\/deployment-target.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3132\" src=\"\/xcode\/wp-content\/uploads\/2016\/08\/deployment-target.png\" alt=\"\" width=\"640\" height=\"156\" \/><\/a><br \/>\n\u00c0 partir de iOS 11, <a href=\"https:\/\/www.dailydot.com\/debug\/ios-11-facebook-twitter-social-integration\/\">les r\u00e9seaux sociaux ne sont plus int\u00e9gr\u00e9s \u00e0 la plate-forme<\/a>. \u00a0Il faudra \u00e0 l&rsquo;avenir utiliser les frameworks natifs des r\u00e9seaux sociaux.<br \/>\nPar exemple, pour twitter les instructions sont <a href=\"https:\/\/dev.twitter.com\/twitterkit\/ios\/migrate-social-framework\">ici<\/a>.<\/p>\n<h1>Contenu<\/h1>\n<p><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final1_.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft wp-image-1050\" style=\"margin-right: 50px;\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final1_.png\" alt=\"TIM.Magazine.final1\" width=\"276\" height=\"383\" \/><\/a><\/p>\n<ul>\n<li>\u00c9laboration d\u2019une interface utilisateur<\/li>\n<li>Chargement et suppression de sc\u00e8nes par programmation<\/li>\n<li>Capture de la sc\u00e8ne vers une image<\/li>\n<li>Enregistrement d\u2019une image dans l\u2019album photo<\/li>\n<li>Ajout et utilisation du \u2018framework\u2019 \u2018social\u2019<\/li>\n<li>Configuration d\u2019un compte \u2018twitter\u2019 et \u2018facebook\u2019 sous iOS<\/li>\n<li>Publication, par programmation, de messages sur \u2018twitter\u2019 et \u2018facebook\u2019<\/li>\n<li>Programmation d\u2019\u00e9v\u00e9nements<\/li>\n<li>Utilisation de la POO<\/li>\n<\/ul>\n<h1><\/h1>\n<h1><\/h1>\n<h1><\/h1>\n<h1><\/h1>\n<h1><\/h1>\n<h1><\/h1>\n<hr \/>\n<h1>Description<\/h1>\n<p><span style=\"color: #5f5f5f;\">Avec ce tutoriel nous apprendrons \u00e0 programmer une application iOS qui offre \u00e0 l\u2019utilisateur la possibilit\u00e9 d\u2019habiller sa photo \u00e0 partir de\u00a0maquettes de magazines et de pouvoir publier le r\u00e9sultat sur les r\u00e9seaux sociaux \u2018facebook\u2019 et \u2018twitter\u2019.<\/span><br \/>\n<span style=\"color: #5f5f5f;\">Vid\u00e9o du r\u00e9sultat final:<\/span><br \/>\n[embedyt]http:\/\/www.youtube.com\/watch?v=CucHHI7697g[\/embedyt]<br \/>\n<span style=\"color: #ff0000;\">Note: Le texte en rouge indique une t\u00e2che \u00e0 r\u00e9aliser en laboratoire.<\/span><\/p>\n<hr \/>\n<h1>\u00c9tape 1 \u2013 R\u00e9alisation de la sc\u00e8ne principale<\/h1>\n<p><strong><span style=\"color: #ff0000;\">Action 1<\/span><\/strong>\u00a0&#8211; Cr\u00e9ons un nouveau projet de type \u201cSingle View\u201d pour le \u2018iPad\u2019.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_new_Xcode_project.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-985\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_new_Xcode_project.png\" alt=\"TIM_Magazine_new_Xcode_project\" width=\"733\" height=\"431\" \/><\/a><br \/>\n<strong><span style=\"color: #ff0000;\">Action 2<\/span><\/strong>\u00a0&#8211; Renseignons les information de cr\u00e9ation du projet<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_new_TIM-Magazine.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-984\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_new_TIM-Magazine.png\" alt=\"TIM_Magazine_new_TIM-Magazine\" width=\"733\" height=\"436\" \/><\/a><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3<\/strong><\/span>\u00a0&#8211; Ajoutons au projet un &lsquo;groupe&rsquo; nomm\u00e9 &lsquo;Mes ressources&rsquo;.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_new_group.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-983\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_new_group.png\" alt=\"TIM_Magazine_new_group\" width=\"391\" height=\"300\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_name_new_group.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-982\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_name_new_group.png\" alt=\"TIM_Magazine_name_new_group\" width=\"262\" height=\"230\" \/><\/a><\/p>\n<hr \/>\n<h1>Voici les ressources du projet<\/h1>\n<p><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image002.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-962\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image002.png\" alt=\"TIM.Magazine.image002\" width=\"97\" height=\"97\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image003.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-963\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image003.png\" alt=\"TIM.Magazine.image003\" width=\"107\" height=\"107\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image001.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-961\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image001.png\" alt=\"TIM.Magazine.image001\" width=\"413\" height=\"388\" \/><\/a><\/p>\n<h1>Ajouter les\u00a0images au projet<\/h1>\n<p><span style=\"color: #ff0000;\"><strong>Action 4<\/strong><\/span>\u00a0&#8211; Ajoutons les trois images pr\u00e9c\u00e9dentes au projet.<br \/>\n<strong>Astuce<\/strong>: \u00a0Il faut enregistrer dans &lsquo;download&rsquo; puis, glisser vers le projet.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/Screenshot_2014-07-07_21_22_04.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-979\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/Screenshot_2014-07-07_21_22_04.png\" alt=\"Screenshot_2014-07-07_21_22_04\" width=\"698\" height=\"941\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/Screenshot_2014-07-07_21_24_54.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-980\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/Screenshot_2014-07-07_21_24_54.png\" alt=\"Screenshot_2014-07-07_21_24_54\" width=\"326\" height=\"338\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/Screenshot_2014-07-07_21_26_39.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-981\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/Screenshot_2014-07-07_21_26_39.png\" alt=\"Screenshot_2014-07-07_21_26_39\" width=\"254\" height=\"338\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_cocher_-_copier_au_besoin.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-986\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_cocher_-_copier_au_besoin.png\" alt=\"TIM_Magazine_cocher_-_copier_au_besoin\" width=\"1068\" height=\"438\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.Ajouter-groupe-couvertures.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-990\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.Ajouter-groupe-couvertures.png\" alt=\"TIM.Magazine.Ajouter groupe couvertures\" width=\"235\" height=\"320\" \/><\/a><\/p>\n<h1>\u00c9laboration de la maquette de d\u00e9part<\/h1>\n<p><span style=\"color: #ff0000;\"><strong>Action 5<\/strong><\/span>\u00a0&#8211; Pla\u00e7ons deux contr\u00f4les de type &lsquo;<strong>UIButton<\/strong>&lsquo; au bas de l&rsquo;\u00e9cran et renseignons les propri\u00e9t\u00e9s &lsquo;<strong>Type<\/strong>&lsquo; et &lsquo;<strong>Image<\/strong>&lsquo; pour changer leur apparence.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/Elaborer-la-scene-de-depart.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-992\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/Elaborer-la-scene-de-depart.png\" alt=\"Elaborer la scene de depart\" width=\"1254\" height=\"929\" \/><\/a><\/p>\n<h1>D\u00e9finition des liens &lsquo;MVC&rsquo; entre les boutons et le contr\u00f4leur de la sc\u00e8ne<\/h1>\n<p><strong><span style=\"color: #ff0000;\">Action 6<\/span><\/strong>\u00a0&#8211; Glissons &lsquo;ctrl+clic&rsquo; le bouton &lsquo;facebook&rsquo; vers le\u00a0le contr\u00f4leur de la sc\u00e8ne principale.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_insert_IBAction.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-994\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_insert_IBAction.png\" alt=\"TIM_Magazine_insert_IBAction\" width=\"1565\" height=\"956\" \/><\/a><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 7<\/strong><\/span>\u00a0&#8211; Renseignons les propri\u00e9t\u00e9s du\u00a0lien \u00a0du bouton &lsquo;facebook&rsquo;<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/renseigner-le-IBAction.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-995\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/renseigner-le-IBAction.png\" alt=\"renseigner le IBAction\" width=\"738\" height=\"264\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_IBAction_code.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-996\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_IBAction_code.png\" alt=\"TIM_Magazine_IBAction_code\" width=\"672\" height=\"303\" \/><\/a><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 8<\/strong><\/span>\u00a0&#8211; Ajoutons le code suivant \u00e0 la fonction &lsquo;actionFacebook:<\/p>\n<pre class=\"toolbar:1 lang:default mark:2 decode:true\">@IBAction func actionFacebook(sender: AnyObject) {\n  println(\"actionFacebook\")\n}\n<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Action 9\u00a0<\/strong><\/span>&#8211; Testons l&rsquo;app dans le simulateur:\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/emulateur01.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-999\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/emulateur01.png\" alt=\"emulateur01\" width=\"1297\" height=\"844\" \/><\/a>\u00a0<span style=\"color: #ff0000;\"><strong>Action 10<\/strong><\/span>\u00a0&#8211; Ajoutons une connexion sur le bouton &lsquo;twitter&rsquo;<\/p>\n<pre class=\"toolbar:1 lang:default mark:14-16 decode:true\">\/\/  ViewController.swift\n\/\/  TIM-Magazine.swift\n\/\/  2016.08 - R\u00e9vision swift 3\nimport UIKit\nclass ViewController: UIViewController {\n    \/\/\/ Fonction ex\u00e9cut\u00e9e suite \u00e0 un clic du bouton 'facebook'\n    @IBAction func actionFacebook(sender: AnyObject) {\n        print(\"#actionFacebook\\n\")\n    } \/\/ actionFacebook\n    \/\/\/ Fonction ex\u00e9cut\u00e9e suite \u00e0 un clic du bouton 'twitter'\n    @IBAction func actionTwitter(sender: AnyObject) {\n        print(\"#actionFacebook\\n\")\n    } \/\/ actionTwitter\n    \/\/\/ Fonction ex\u00e9cut\u00e9e suite au chargement de la sc\u00e8ne en m\u00e9moire\n    override func viewDidLoad() {\n        super.viewDidLoad()\n    } \/\/ viewDidLoad\n} \/\/ ViewController\n<\/pre>\n<h1><\/h1>\n<hr \/>\n<h1>\u00c9tape 2 &#8211; \u00c9laboration de base du premier magazine<\/h1>\n<p>Nous allons maintenant ajouter une sc\u00e8ne suppl\u00e9mentaire \u00e0 notre projet.<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 11<\/strong><\/span>\u00a0&#8211; Ajoutons\u00a0un nouveau groupe nomm\u00e9 &lsquo;Les couvertures&rsquo; au projet.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/groupe-couvertures.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1011\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/groupe-couvertures.png\" alt=\"groupe - couvertures\" width=\"235\" height=\"320\" \/><\/a><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 12<\/strong><\/span>\u00a0&#8211; Dans le groupe &lsquo;Les couvertures&rsquo;, ajoutons un nouveau fichier.<br \/>\nExplication en classe de la notion de &lsquo;XIB&rsquo; vs &lsquo;StoryBoard&rsquo;<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1013\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/nouvelle-View.png\" alt=\"nouvelle View\" width=\"378\" height=\"319\" \/><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 13\u00a0<\/strong><\/span>&#8211; S\u00e9lectionnons un fichier\u00a0de type &lsquo;iOS &#8211; User Interface &#8211; View&rsquo;<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1014\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/renseigner-le-fichier-View.png\" alt=\"renseigner le fichier View\" width=\"734\" height=\"430\" \/><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 14<\/strong><\/span>\u00a0&#8211; Nommons la nouvelle sc\u00e8ne<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/nommer-et-enregistrer-fichier-View.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1012\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/nommer-et-enregistrer-fichier-View.png\" alt=\"nommer et enregistrer fichier View\" width=\"733\" height=\"430\" \/><\/a><br \/>\n<strong><span style=\"color: #ff0000;\">Action 15<\/span><\/strong>\u00a0&#8211; Modifions le fond de la sc\u00e8ne et ajoutons un titre.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1010\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/elaboration-de-magazine01.png\" alt=\"elaboration de magazine01\" width=\"1335\" height=\"746\" \/><br \/>\nNote: L&rsquo;ajustement de l&rsquo;alpha du fond de la sc\u00e8ne nous permettra de voir les \u00e9l\u00e9ments sous la sc\u00e8ne lorsqu&rsquo;elle sera ajout\u00e9e \u00e0 la sc\u00e8ne principale.<\/p>\n<hr \/>\n<h1>Chargement d&rsquo;une sc\u00e8ne par programmation<\/h1>\n<p>Il nous reste maintenant \u00e0 charger la sc\u00e8ne &lsquo;magazine01&rsquo; par programmation.<br \/>\nId\u00e9alement, cette sc\u00e8ne devrait \u00eatre affich\u00e9e au d\u00e9marrage de l&rsquo;application.<br \/>\nRappel: \u00a0La sc\u00e8ne est une instance de la classe UIViewController.<br \/>\nLa\u00a0classe &lsquo;UIViewController&rsquo; contient un membre de type &lsquo;UIView&rsquo; qui permet d&rsquo;afficher des \u00e9l\u00e9ments \u00e0 l&rsquo;\u00e9cran.<br \/>\nLa classe &lsquo;UIView&rsquo; propose la m\u00e9thode &lsquo;addSubview&rsquo; pour ajouter des \u00e9lements visuels \u00e0 son canvas d&rsquo;affichage.<br \/>\nDonc, pour ajouter un \u00e9l\u00e9ment \u00e0 la sc\u00e8ne principale, il suffit d&rsquo;appeler la m\u00e9thode &lsquo;addSubview(un objet visuel)&rsquo; du membre &lsquo;view&rsquo; de l&rsquo;instance de la classe de la sc\u00e8ne.<br \/>\nPar exemple, pour ajouter un &lsquo;UILabel&rsquo; \u00e0 l&rsquo;\u00e9cran \u00a0il suffit de programmer: view.addSubView(UILabel()).<br \/>\nNote: \u00ab\u00a0self.view\u00a0\u00bb est valide aussi.<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 16<\/strong><\/span>\u00a0&#8211; Ajoutons le code suivant \u00e0 la m\u00e9thode &lsquo;viewDidLoad&rsquo; du contr\u00f4leur de la sc\u00e8ne principale.<\/p>\n<pre class=\"lang:default mark:8,11 decode:true \">override func viewDidLoad() {\n super.viewDidLoad()\n \/\/ D\u00e9but de notre code...\n       \/\/ Charger le fichier xib\n        let ecranMagazine = UINib(nibName: \"Magazine01\", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView\n        \/\/ Ajuster la taille de la vue \u00e0 la taille de la sc\u00e8ne\n        ecranMagazine.frame = self.view.bounds;\n        \/\/ Ajouter la nouvelle \u2018View\u2019 \u00e0 la sc\u00e8ne principale\n        view.addSubview(ecranMagazine);\n    }\n} \/\/viewDidLoad<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Action 17<\/strong><\/span>\u00a0&#8211; Ex\u00e9cutons le projet dans le simulateur<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/simulateur02.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1017\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/simulateur02.png\" alt=\"simulateur02\" width=\"576\" height=\"784\" \/><\/a><br \/>\n<strong>Solution<\/strong>: \u00a0Ins\u00e9rer la maquette avant les boutons.<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 18<\/strong><\/span>\u00a0&#8211; Observons la structure des \u00e9l\u00e9ments de la sc\u00e8ne<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/inserer-magazine-avant-les-boutons.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1018\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/inserer-magazine-avant-les-boutons.png\" alt=\"inserer magazine avant les boutons\" width=\"959\" height=\"796\" \/><\/a><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 19<\/strong><\/span>\u00a0&#8211; Modifions le code, pour ajouter le magazine avant les boutons &lsquo;facebook&rsquo; et &lsquo;twitter&rsquo;<\/p>\n<pre class=\"lang:default mark:3 decode:true \">\/\/ Ins\u00e9rer la nouvelle \u2018View\u2019 avant les boutons fb et twitter\nprint(\"#view.subviews.count: \\(view.subviews.count)\\n\")\nview.insertSubview(ecranMagazine, at: (view.subviews.count - 2) - 1 )\n\/\/ Ou bien ceci pour ajouter au haut de la liste\nview.insertSubview(ecranMagazine, at: 0)<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: S&rsquo;il y a des guides de mise en page, il faut les ajouter au calcul.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2016\/08\/guides_de_mise_en_page.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2752\" src=\"\/xcode\/wp-content\/uploads\/2016\/08\/guides_de_mise_en_page.png\" alt=\"guides_de_mise_en_page\" width=\"270\" height=\"208\" \/><\/a><br \/>\nCe qui donne le r\u00e9sultat suivant:<\/p>\n<pre class=\"lang:swift decode:true \">view.insertSubview(ecranMagazine, at: (view.subviews.count - (2 + 2)) - 1 )<\/pre>\n<p><strong><span style=\"color: #ff0000;\">Action 20<\/span><\/strong>\u00a0&#8211; Ex\u00e9cutons le projet dans le simulateur<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/simulateur03.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1020\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/simulateur03.png\" alt=\"simulateur03\" width=\"1080\" height=\"799\" \/><\/a><\/p>\n<h1>Regroupement des \u00e9l\u00e9ments d&rsquo;interaction<\/h1>\n<p>L&rsquo;approche pr\u00e9c\u00e9dente pose un probl\u00e8me, il faudra modifier l&rsquo;indice d\u2019insertion \u00e0 chaque fois que nous ajouterons des \u00e9l\u00e9ments de contr\u00f4le \u00e0 la sc\u00e8ne principale.<br \/>\nPar exemple, un menu pour changer de magazine.<br \/>\nIl est possible de regrouper des objets visuels ensemble gr\u00e2ce \u00e0 l&rsquo;objet &lsquo;UIView&rsquo;.<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 21<\/strong><\/span>\u00a0&#8211; Ajoutons un objet &lsquo;UIView&rsquo; \u00e0 la sc\u00e8ne principale.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/ajouter-viewMenu.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1022\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/ajouter-viewMenu.png\" alt=\"ajouter viewMenu\" width=\"754\" height=\"727\" \/><\/a><br \/>\n<strong><span style=\"color: #ff0000;\">Action 22<\/span><\/strong>\u00a0&#8211; Rempla\u00e7ons la valeur de \u00a0param\u00e8tre &lsquo;atIndex&rsquo; pour &lsquo;view.subviews.count &#8211; 1&Prime;<\/p>\n<pre class=\"lang:swift decode:true\">\/\/ Avec les guides de mise en page\nview.insertSubview(ecranMagazine, at: view.subviews.count - 3 )\n\/\/ Sans guides\nview.insertSubview(ecranMagazine, at: view.subviews.count - 1 )\n\/\/ Oui bien, ins\u00e9rer la vue au fond de la sc\u00e8ne principale:\nview.insertSubview(ecranMagazine, at: 0)\n<\/pre>\n<p><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/simulateur-avec-menu1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1024\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/simulateur-avec-menu1.png\" alt=\"simulateur avec menu\" width=\"865\" height=\"623\" \/><\/a><\/p>\n<h1>Quelques petits ajustements<\/h1>\n<p><span style=\"color: #ff0000;\"><strong>Action 23<\/strong><\/span>\u00a0&#8211; Renseignons le fond de la sc\u00e8ne principale \u00e0 \u00ab\u00a0noir\u00a0\u00bb et le fond de la maquette &lsquo;Magazine01&prime; \u00e0 \u00ab\u00a0Clear color&rsquo; (transparent).<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/scene-fond-a-noir.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1026\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/scene-fond-a-noir.png\" alt=\"scene fond a noir\" width=\"960\" height=\"308\" \/><\/a>\u00a0<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1025\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/fond-magazine01.png\" alt=\"fond magazine01\" width=\"955\" height=\"465\" \/><br \/>\n<strong><span style=\"color: #ff0000;\">Action 24<\/span><\/strong>\u00a0&#8211; Testons avec le simulateur:<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/etape01.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1027\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/etape01.png\" alt=\"etape01\" width=\"574\" height=\"789\" \/><\/a><br \/>\n<strong><span style=\"color: #0000ff;\">R\u00e9flexion<\/span><\/strong>: \u00a0Nous assumons que la &lsquo;view&rsquo; du fichier XIB sera toujours \u00e0 la position [0] du XIB. \u00a0Si Apple change la position de la &lsquo;view&rsquo;, notre programme ne fonctionnera plus correctemnt.<br \/>\nLa m\u00e9thode recommand\u00e9e par Apple pour charger la &lsquo;view&rsquo; du fichier XIB est la suivante:<\/p>\n<pre class=\"lang:swift decode:true \">\/\/: NOTE, Ne pas utiliser ce code dans votre projet!\nvar ecranMagazine2 = UIView()\n\/\/ Parcourir tous les \u00e9l\u00e9ments du fichier\nfor x in UINib(nibName: \"magazine01\", bundle: nil).instantiate(withOwner: nil, options: nil) {\n  \/\/ si objet courant de type 'UIView' alors renseigner notre variable\n   if x.isKind(of:UIView.self) {\n      print(\"#Nous avons trouv\u00e9 la View!\\n\")\n      ecranMagazine2 = x as! UIView\n    } \/\/ if\n} \/\/ for\n<\/pre>\n<hr \/>\n<h1>\u00c9tape 03 &#8211; Design\u00a0des maquettes<\/h1>\n<p><strong><span style=\"color: #ff0000;\">Action 25<\/span><\/strong>\u00a0&#8211; Vous devez r\u00e9aliser les maquettes suivantes:<br \/>\n<strong>Note<\/strong>: \u00a0Pendant l\u2019\u00e9tape d\u2019\u00e9laboration des maquettes, il est recommand\u00e9 de fixer la couleur de la sc\u00e8ne \u00e0 noir. \u00a0Cela va permettre de distinguer le texte blanc. Nous changerons le fond de \u2018noir\u2019 \u00e0 \u2018transparent : clearcolor\u2019 \u00e0 l\u2019\u00e9tape de chargement des interfaces.<br \/>\n<strong><span style=\"color: #339966;\">Astuce<\/span><\/strong>: Pensez \u00e0 copier\/coller le fichier Magazine01.xib vers 02..04.xib.<\/p>\n<h2>Magazine 01<\/h2>\n<h2><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/magazine01.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1034\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/magazine01.png\" alt=\"magazine01\" width=\"773\" height=\"1026\" \/><\/a><\/h2>\n<h2>Magazine 02<\/h2>\n<h2><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/magazine02.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1035\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/magazine02.png\" alt=\"magazine02\" width=\"766\" height=\"1024\" \/><\/a><\/h2>\n<h2>Magazine 03<\/h2>\n<h2><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/magazine03.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1036\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/magazine03.png\" alt=\"magazine03\" width=\"764\" height=\"1022\" \/><\/a><\/h2>\n<h2>Magazine 04 (votre design perso)<\/h2>\n<h2><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/magazine04.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1037\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/magazine04.png\" alt=\"magazine04\" width=\"769\" height=\"1024\" \/><\/a><\/h2>\n<p>Les ressources<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image012.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-965\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image012.jpg\" alt=\"TIM.Magazine.image012\" width=\"115\" height=\"80\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image011.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-964\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.image011.png\" alt=\"TIM.Magazine.image011\" width=\"133\" height=\"97\" \/><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1653\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/Rolling_Stone_logo.png\" alt=\"Rolling_Stone_logo\" width=\"1252\" height=\"263\" \/><\/a><\/p>\n<hr \/>\n<h1>\u00c9tape 04 &#8211; Tourner les pages avec un menu<\/h1>\n<p><span style=\"color: #ff0000;\"><strong>Action 26<\/strong><\/span>\u00a0&#8211; Ajoutons un &lsquo;UISegmentedControl&rsquo; dans la section interactive.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.segmented.control.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1041\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.segmented.control.png\" alt=\"TIM.Magazine.segmented.control\" width=\"1191\" height=\"376\" \/><\/a><br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.titre_.segments.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1042\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.titre_.segments.png\" alt=\"TIM.Magazine.titre.segments\" width=\"562\" height=\"225\" \/><\/a><br \/>\nR\u00e9sultat final:<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.titre_.segments.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1040\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.segmented.control.final_.png\" alt=\"TIM.Magazine.segmented.control.final\" width=\"382\" height=\"87\" \/><\/a><br \/>\nD\u00e9finissons un lien IBAction sur le \u00a0&lsquo;UISegmentedControl&rsquo;<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.segmented.control.IBAction.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1044\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.segmented.control.IBAction.png\" alt=\"TIM.Magazine.segmented.control.IBAction\" width=\"1048\" height=\"464\" \/><\/a><\/p>\n<div class=\"page\" title=\"Page 11\">\n<div class=\"layoutArea\">\n<div class=\"column\"><span style=\"color: rgb(100.000000%, 0.000000%, 0.000000%);\">Pla\u00e7ons une trace\u00a0<\/span>dans la m\u00e9thode \u2018actionTournerPages\u2019 pour confirmer qu\u2019il y a effectivement appel suite \u00e0 une s\u00e9lection.<\/div>\n<\/div>\n<\/div>\n<pre class=\"lang:default mark:3 decode:true\">\/\/\/ Fonction ex\u00e9cut\u00e9e suite \u00e0 une s\u00e9lection dans le 'UISegmentedControl'.  Note: Doit-\u00eatre li\u00e9e au UISC.\n@IBAction func actionTournerPages(sender: UISegmentedControl) {\n  let selection = sender.selectedSegmentIndex\n  print(\"#actionTournerPages: la s\u00e9lection vaut: \\(selection)\\n\")\n}<\/pre>\n<p><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.segmented.control.selection.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1046\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.segmented.control.selection.png\" alt=\"TIM.Magazine.segmented.control.selection\" width=\"872\" height=\"816\" \/><\/a><\/p>\n<div class=\"page\" title=\"Page 12\">\n<div class=\"layoutArea\">\n<div class=\"column\">De fa\u00e7on empirique, nous constatons que l\u2019objet \u2018<span style=\"color: rgb(36.100000%, 14.900000%, 60.000000%);\">UISegmentedControl<\/span>\u2019 retourne une valeur entre 0 et nb\u00c9l\u00e9ments-1.<br \/>\nIl ne reste plus qu\u2019\u00e0 programmer une structure logique qui ins\u00e9rera la couverture magazine correspondant \u00e0 la s\u00e9lection de l\u2019utilisateur.<br \/>\nNote :<br \/>\nPour enlever un objet de la sc\u00e8ne il faut utiliser la syntaxe suivante :<br \/>\n<span style=\"color: rgb(24.700000%, 43.100000%, 45.500000%);\">ecranMagazine.<\/span><span style=\"color: rgb(18.000000%, 5.100000%, 43.100000%);\">removeFromSuperview()<\/span><br \/>\nNote: Il est important de d\u00e9clarer la variable &lsquo;<span style=\"color: #3f6e74;\">ecranMagazine<\/span>&lsquo;\u00a0comme propri\u00e9t\u00e9 de la classe de la sc\u00e8ne.<br \/>\n<span style=\"color: #c32275;\">class<\/span>\u00a0ViewController:\u00a0<span style=\"color: #6122ae;\">UIViewController<\/span>\u00a0{<br \/>\n<span style=\"color: #c32275;\">var<\/span>\u00a0ecranMagazine = \u00a0<span style=\"color: #6122ae;\">UIView()<\/span><br \/>\n&#8230;<br \/>\nfunc chargerMagazine(no:Int) {<br \/>\nvar nomMagazine = &#8230;<br \/>\n<span style=\"color: #539aa4;\">\u00a0 ecranMagazine<\/span>\u00a0=\u00a0<span style=\"color: #6122ae;\">UINib<\/span>(nibName: nomMagazine, bundle:\u00a0<span style=\"color: #c32275;\">nil<\/span>).<span style=\"color: #3d1d81;\">instantiate<\/span>(withOwner:\u00a0<span style=\"color: #c32275;\">nil<\/span>, options:\u00a0<span style=\"color: #c32275;\">nil<\/span>)[<span style=\"color: #0435ff;\">0<\/span>]\u00a0<span style=\"color: #c32275;\">as\u00a0<\/span>\u00a0<span style=\"color: #6122ae;\">UIView<br \/>\n<\/span>\u00a0 } \/\/\u00a0chargerMagazine<br \/>\n} \/\/ \u00a0ViewController<\/p>\n<div class=\"page\" title=\"Page 12\">\n<div class=\"layoutArea\">\n<div class=\"column\"><span style=\"font-weight: bold; color: rgb(31.000000%, 50.600000%, 74.100000%);\">\u00c0 faire par l\u2019\u00e9tudiant en laboratoire\u00a0<\/span><br \/>\n<span style=\"color: rgb(100.000000%, 0.000000%, 0.000000%);\">Programmer le chargement de la maquette de magazine correspondant au choix de l\u2019utilisateur.\u00a0<\/span><br \/>\n<span style=\"color: rgb(100.000000%, 0.000000%, 0.000000%);\">Il est important de normaliser le code. Pas de structures lourdes dans votre code. Ne pas utiliser l\u2019instruction \u2018if\u2019 ou \u2018switch\u2019.\u00a0<\/span><br \/>\n<span style=\"color: rgb(100.000000%, 0.000000%, 0.000000%);\">Il est possible de r\u00e9aliser la t\u00e2che avec un maximum de 4 lignes de code :\u00a0<\/span><\/div>\n<\/div>\n<\/div>\n<pre class=\"lang:default decode:true\">@IBAction func actionTournerPages(sender: AnyObject) {\n\/\/ 1 - Retirer le magazine courant de la sc\u00e8ne\n\/\/ 2 - Construire une chaine de caract\u00e8res qui d\u00e9crit le nom du fichier: 'Magazine0' + selectionCourante + 1\n\/\/ 3 - Charger le magazine \u00e0 partir d\u2019un nom d\u2019un fichier NIB\n\/\/ 4 - Ajouter le magazine \u00e0 la sc\u00e8ne principale\n}\n<\/pre>\n<p>R\u00e9sultat:<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final1_.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1050\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final1_.png\" alt=\"TIM.Magazine.final1\" width=\"276\" height=\"383\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final2_.png\">\u00a0<\/a><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final2_.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1051\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final2_.png\" alt=\"TIM.Magazine.final2\" width=\"276\" height=\"383\" \/><\/a>\u00a0\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final3_.png\"><img decoding=\"async\" class=\"alignnone wp-image-1052\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final3_.png\" alt=\"TIM.Magazine.final3\" height=\"383\" \/><\/a>\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final4_.png\">\u00a0<\/a><a href=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final4_.png\"><img decoding=\"async\" class=\"alignnone wp-image-1053\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM.Magazine.final4_.png\" alt=\"TIM.Magazine.final4\" height=\"383\" \/><\/a><\/p>\n<hr \/>\n<h1>\u00c9tape 5 &#8211; Int\u00e9gration des r\u00e9seaux sociaux<\/h1>\n<\/div>\n<\/div>\n<\/div>\n<p>PR\u00c9-REQUIS &#8211; Configuration des comptes sociaux sur l&rsquo;appareil iOS.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1285 size-full\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_08.png\" alt=\"TIM_Magazine_08\" width=\"768\" height=\"416\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1284 size-full\" src=\"\/xcode\/wp-content\/uploads\/2014\/07\/TIM_Magazine_07.png\" alt=\"TIM_Magazine_07\" width=\"766\" height=\"1047\" \/><br \/>\nCapture d&rsquo;une Vue vers un objet UIImage<\/p>\n<pre class=\"lang:swift decode:true\">    func sauvegarderEcran(){\n        \/\/ Description : m\u00e9thode servant \u00e0 capturer l\u2019\u00e9cran et au besoin,\n        \/\/ en faire une sauvegarde dans l\u2019album photos.\n        \/\/ Cacher le menu\n        leMenu.isHidden = true\n        \/\/ 1 - Pr\u00e9parer un contexte de dessin \u00e0 partir de la taille de la sc\u00e8ne\n        UIGraphicsBeginImageContext(self.view.bounds.size);\n        \/\/ 2 \u2013 Dessiner \u00e0 partir du claque par d\u00e9faut de la sc\u00e8ne\n        self.view.layer.render(in: UIGraphicsGetCurrentContext()!);\n        \/\/ 3 \u2013 Stocker le r\u00e9sultat dans notre objet local\n        imageFinale = UIGraphicsGetImageFromCurrentImageContext()!;\n        \/\/ 5 \u2013 Fermer le contexte de dessin\n        UIGraphicsEndImageContext();\n        \/\/ 6 \u2013 Facultatif - Stocker une copie de la capture d\u2019\u00e9cran dans l\u2019album photos\n        \/\/ Note:  \u00c0 partir de iOS 10: Info.plist doit contenir une cl\u00e9 'NSPhotoLibraryUsageDescription' de type 'String' qui indique \u00e0 l'utilisateur comment sera utilis\u00e9 sa librairie de photos.\n        UIImageWriteToSavedPhotosAlbum(imageFinale, nil, nil, nil );\n        leMenu.isHidden = false\n    } \/\/ sauvegarderEcran<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Action<\/strong><\/span> &#8211;\u00a0Ajouter le code suivant dans la m\u00e9thode posterSurFacebook:<\/p>\n<pre class=\"lang:swift decode:true\">sauvegarderEcran()<\/pre>\n<p><strong><span style=\"color: #ff0000;\">Action<\/span><\/strong> &#8211; Tester l&rsquo;application:<br \/>\n<strong><span style=\"color: #ff0000;\">Note<\/span><\/strong>: Sous iOS 10, il devrait y avoir l&rsquo;erreur suivante:<\/p>\n<blockquote><p>TIM.Magazine[16985:6613925] [access] This app has crashed because it attempted to access privacy-sensitive data without a usage description.\u00a0 The app&rsquo;s Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.<\/p><\/blockquote>\n<p><span style=\"color: #ff0000;\"><strong>Action<\/strong><\/span>: Ajouter au fichier &lsquo;Info.plist&rsquo; la cl\u00e9 &lsquo;NSPhotoLibraryUsageDescription&rsquo;:<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2016\/08\/privacy-photo01.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2755\" src=\"\/xcode\/wp-content\/uploads\/2016\/08\/privacy-photo01.png\" alt=\"privacy-photo01\" width=\"766\" height=\"621\" \/><\/a><br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2016\/08\/privacy-photo02.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2756\" src=\"\/xcode\/wp-content\/uploads\/2016\/08\/privacy-photo02.png\" alt=\"privacy-photo02\" width=\"517\" height=\"247\" \/><\/a><br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2016\/08\/privacy-photo03.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2757\" src=\"\/xcode\/wp-content\/uploads\/2016\/08\/privacy-photo03.png\" alt=\"privacy-photo03\" width=\"573\" height=\"22\" \/><\/a><br \/>\n<span style=\"color: #ff0000;\">Attention: <span style=\"color: #000000;\">\u00c0 partir de Xcode 9 il faut plut\u00f4t ajouter la cl\u00e9 &lsquo;NSPhotoLibraryAddUsageDescription&rsquo;<\/span><\/span><br \/>\nOu bien en \u00e9ditant le fichier info.plist et en ajoutant le code suivant:<\/p>\n<pre class=\"lang:swift decode:true\">\t&lt;key&gt;NSPhotoLibraryUsageDescription&lt;\/key&gt;\n\t&lt;string&gt;Puis-je utiliser votre album photo?&lt;\/string&gt;\n<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Action<\/strong><\/span>\u00a0&#8211; Tester l&rsquo;application:<br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: Sous iOS 10, il ne devrait plus y avoir d&rsquo;erreur:<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2016\/08\/privacy-photo04.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2759\" src=\"\/xcode\/wp-content\/uploads\/2016\/08\/privacy-photo04.png\" alt=\"privacy-photo04\" width=\"217\" height=\"140\" \/><\/a><br \/>\n<span style=\"color: #ff0000;\"><strong>Action<\/strong><\/span>: V\u00e9rifions la pr\u00e9sence de la capture dans l&rsquo;album de photos du simulateur. (Maj+CMD+h)<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2016\/08\/album-photos01.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2760 size-medium\" src=\"\/xcode\/wp-content\/uploads\/2016\/08\/album-photos01-437x600.png\" alt=\"album-photos01\" width=\"437\" height=\"600\" \/><\/a><br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2016\/08\/album-photos02.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2761 size-medium\" src=\"\/xcode\/wp-content\/uploads\/2016\/08\/album-photos02-438x600.png\" alt=\"album-photos02\" width=\"438\" height=\"600\" \/><\/a><\/p>\n<hr \/>\n<h1><\/h1>\n<h1>Envoyer un &lsquo;post&rsquo; vers Facebook<\/h1>\n<pre class=\"lang:swift decode:true\">import Social\n   func posterSurFacebook() {\n        \/\/ Les \u00e9tapes pour utiliser \u2018facebook\u2019\n        \/\/ 1 - Tester si le service et les informations de connexion sont dispo\n        if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeFacebook)\n        {\n            \/\/ 2 - Cr\u00e9er un feuille pour le 'post'\n            if let controleur = SLComposeViewController (forServiceType: SLServiceTypeFacebook) {\n            \/\/ 3 - Composer le message\n            controleur.setInitialText(\"Test avec Swift 3 et Xcode 8\");\n            self.present(controleur, animated: true, completion: nil);\n            \/\/ 4 - Ajouter une image - facultatif\n            controleur.add(imageFinale);\n            \/\/ 5 - Ajouter un lien - facultatif\n            controleur.add(NSURL(fileURLWithPath: \"http:\/\/tim.cstj.qc.ca\") as URL!);\n            \/\/ 6 - Pr\u00e9senter la fen\u00eatre de confirmation \u00e0 l'utilisateur\n            \/\/ self.present(controleur, animated: true, completion: nil);\n            \/\/ Ne fonctionne plus pour Facebook sous Xcode 8B5.  Par contre, fonctionne avec twitter.\n            \/\/ Temporairement remplacer par:\n            self.navigationController?.pushViewController(controleur, animated: true)\n            }\n        } \/\/ if Facebook\n    } \/\/ posterSurFacebook<\/pre>\n<p><strong><span style=\"color: #ff0000;\">Action<\/span><\/strong> &#8211; Modifier la m\u00e9thode &lsquo;actionFacebook&rsquo;.<\/p>\n<pre class=\"lang:swift mark:4 decode:true \">    @IBAction func actionFacebook(sender: AnyObject) {\n        print(\"actionFacebook\")\n        sauvegarderEcran()\n        posterSurFacebook()\n    } \/\/ actionFacebook\n<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Action<\/strong><\/span> &#8211; Tester l&rsquo;application<br \/>\nAttention &#8211; Assurez-vous de tester avec un simulateur sous iOS 10. \u00a0Les choses se sont s\u00e9rieusement compliqu\u00e9es sous iOS 11.<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2016\/08\/post-sur-fb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2762 size-medium\" src=\"\/xcode\/wp-content\/uploads\/2016\/08\/post-sur-fb-438x600.png\" alt=\"post-sur-fb\" width=\"438\" height=\"600\" \/><\/a><br \/>\n<strong><span style=\"color: #ff0000;\">Action<\/span><\/strong> &#8211; Modifier le m\u00e9thode actionTwitter<br \/>\nIl reste \u00e0 cacher la zone menu avant de capturer l&rsquo;\u00e9cran.<br \/>\nD\u00e9finissons un IBOutlet sur la View du menu.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1279 size-full\" src=\"\/xcode\/wp-content\/uploads\/2014\/06\/TIM_Magazine_06.png\" alt=\"TIM_Magazine_06\" width=\"1011\" height=\"536\" \/><br \/>\nAjoutons le code suivant \u00e0 la m\u00e9thode capturerEcran.<\/p>\n<pre class=\"lang:swift mark:4,9 decode:true \">    func sauvegarderEcran(){\n       \/\/ Cacher le menu\n        leMenu.isHidden = true\n        \/\/ 1  ...\n        \/\/ 6\n        leMenu.isHidden = false\n     } \/\/ sauvegarderEcran<\/pre>\n<hr \/>\n<h1>\u00c9tape 6 &#8211; Utilisation d&rsquo;un UIScrollView<\/h1>\n<p><span style=\"color: #ff0000;\"><strong>Note<\/strong>: Cette \u00e9tape est facultative. \u00a0Il n&rsquo;y aura pas d&rsquo;explication en classe, Si vous la r\u00e9alisez, la correction du projet se fera sur\u00a0<strong>12\/10<\/strong>. \u00a0Si vous optez pour cette option, il faudra le pr\u00e9ciser dans votre archive de remise.<\/span><br \/>\nLe contr\u00f4le &lsquo;UIScrollView&rsquo; permet d&rsquo;afficher un contenu plus grand que sa\u00a0zone d&rsquo;affichage.<br \/>\nUne gestuelle sur l&rsquo;\u00e9cran donne acc\u00e8s au contenu non visible.<br \/>\nM\u00e9thode d&rsquo;utilisation du contr\u00f4le:<br \/>\n1 &#8211; Placer le &lsquo;UIScrollView&rsquo; sur une sc\u00e8ne,<br \/>\n2 &#8211; Par programmation, ajouter des objets dans le\u00a0&lsquo;UIScrollView&rsquo; en renseignant correctement les positions x\/y,<br \/>\n3 &#8211; Renseigner \u00a0la propri\u00e9t\u00e9\u00a0\u00a0&lsquo;UIScrollView&rsquo;.contentSize<\/p>\n<pre class=\"lang:swift decode:true\">    func chargerLesMagazines() {\n        \/\/ Renseigner la largeur de la zone de contenu du scrollView en fn du nb de pages.\n        let pagesScrollViewSize = zoneAffichageDesElements.frame.size\n        zoneAffichageDesElements.contentSize = CGSizeMake(pagesScrollViewSize.width * Float(nbMagazines), pagesScrollViewSize.height)\n        for page in 0..&lt;nbMagazines {\n            \/\/ Placer les Views un \u00e0 la suite de l'autre sur le plan des 'x'\n            var frame:CGRect = zoneAffichageDesElements.bounds\n            frame.origin.x = frame.size.width * Float(page)  \/\/ la premi\u00e8re page (0) sera \u00e0 x = 0\n            frame.origin.y = 0\n            \/\/ Charger le 'xib' courant\n            var nomNIB = \"Magazine0\\(page+1)\"\n            println(nomNIB)\n            if var newPageView = UINib(nibName: nomNIB, bundle: nil).instantiateWithOwner(nil, options: nil)[0] as? UIView {\n                newPageView.frame = frame;\n                \/\/ Ajouter au scrollView\n                zoneAffichageDesElements.addSubview(newPageView)\n            }  \/\/ if newPageView\n        } \/\/ for page\n    } \/\/ chargerLesMagazines()<\/pre>\n<p>Testons<br \/>\nActivons le &lsquo;paging enable&rsquo;<br \/>\nAjoutons un UIPageControl (indicateur de la page courante\/nbPages)<br \/>\nExpliquer D\u00e9l\u00e9gation<\/p>\n<pre class=\"lang:swift decode:true \">   \/\/ Une des M\u00e9thodes de d\u00e9l\u00e9gation de UIScrollView\n    func scrollViewDidEndDecelerating(scrollView: UIScrollView){\n        println(\"scrollViewDidEndDecelerating\")\n        let positionPage = Int(zoneAffichageDesElements.contentOffset.x \/ zoneAffichageDesElements.frame.size.width)\n        indicateurDePages.currentPage = positionPage\n    }  \/\/ scrollViewDidEndDecelerating<\/pre>\n<p>Rempla\u00e7ons \u00a0le code de la m\u00e9thode &lsquo;viewDidLoad.<\/p>\n<pre class=\"lang:swift decode:true \">    override func viewDidLoad() {\n        super.viewDidLoad()\n        \/\/ D\u00e9but de notre code...\n        \/\/ L'ancien code de chargement du magazine01 doit-\u00eatre supprim\u00e9.\n        chargerLesMagazines()\n    }  \/\/ viewDidLoad<\/pre>\n<p>Un exemple de <a href=\"https:\/\/bitbucket.org\/alain_boudreault\/utilisation-dun-scrollview-swift-3\/downloads\/\">scrollView<\/a><br \/>\nFIN \u00a0du laboratoire<\/p>\n<hr \/>\n<h6 style=\"text-align: right;\">Document r\u00e9dig\u00e9 par Alain Boudreault &#8211; Juillet 2014 &#8211; R\u00e9vision: \u00a0septembre 2017<\/h6>\n","protected":false},"excerpt":{"rendered":"<p>Note: Sous Xcode 9, il faut choisir un &lsquo;deployment target&rsquo; inf\u00e9rieure \u00e0 iOS 11.0. \u00a0Au besoin, installer un simulateur roulant la version 10.3 de iOS.\u00a0 \u00c0 partir de iOS 11, les r\u00e9seaux sociaux ne sont plus int\u00e9gr\u00e9s \u00e0 la plate-forme. \u00a0Il faudra \u00e0 l&rsquo;avenir utiliser les frameworks natifs des r\u00e9seaux sociaux. Par exemple, pour twitter [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2751","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/pages\/2751","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/comments?post=2751"}],"version-history":[{"count":1,"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/pages\/2751\/revisions"}],"predecessor-version":[{"id":3495,"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/pages\/2751\/revisions\/3495"}],"wp:attachment":[{"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/media?parent=2751"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}