<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-4212984476274343535</atom:id><lastBuildDate>Sun, 18 Jan 2026 07:58:43 +0000</lastBuildDate><category>ios</category><category>XCode</category><category>iphone</category><category>tutorial</category><category>app</category><category>custom</category><category>objective c</category><category>design</category><category>Spritekit</category><category>apps</category><category>development</category><category>ipod</category><category>to</category><category>api</category><category>example</category><category>for</category><category>game</category><category>ipad</category><category>SKLabelNode</category><category>animation</category><category>beginner</category><category>buttons</category><category>coding</category><category>developer</category><category>dynamic</category><category>easy</category><category>hack</category><category>how</category><category>iamja77</category><category>implementation</category><category>integration</category><category>interface</category><category>iphonex</category><category>newbie</category><category>obj c</category><category>object</category><category>sample</category><category>uitableviewcell</category><category>upload</category><category>7</category><category>8</category><category>8bit</category><category>CoreAnimation</category><category>IAP</category><category>MKMApview</category><category>MKTileOverlay</category><category>NSString</category><category>Photos</category><category>QuickTime</category><category>SKScene</category><category>UIAlertView</category><category>UIImageView</category><category>UIpickerview</category><category>UItabbar</category><category>aboutbox</category><category>adding</category><category>admob</category><category>app list</category><category>application</category><category>approach</category><category>area</category><category>art</category><category>atari</category><category>automation</category><category>background</category><category>ball</category><category>basic</category><category>between</category><category>bit</category><category>block</category><category>border</category><category>caemitter</category><category>caemittercell</category><category>caemitterlayer</category><category>calendar</category><category>can</category><category>cell</category><category>cgcontext</category><category>class</category><category>clone</category><category>cocoapods</category><category>cocos2d</category><category>code</category><category>colors</category><category>command lines</category><category>comparing</category><category>completion</category><category>considerations</category><category>conversion</category><category>coregraphics</category><category>customizable</category><category>customize</category><category>damage</category><category>data</category><category>delegates</category><category>deprecated</category><category>designer</category><category>designing</category><category>dev</category><category>distribution</category><category>drive</category><category>dvd</category><category>easiest</category><category>effects</category><category>embed</category><category>facebook</category><category>files</category><category>fill</category><category>flashing</category><category>flat</category><category>flow</category><category>framework</category><category>free</category><category>function</category><category>functions</category><category>gif</category><category>global</category><category>guide</category><category>guidelines</category><category>help</category><category>horizontal pickerview</category><category>how to</category><category>human</category><category>iad</category><category>image</category><category>images</category><category>implementing</category><category>in</category><category>in app purchase</category><category>inherit</category><category>inkscape</category><category>installation</category><category>installer</category><category>intergrating</category><category>intersections</category><category>ios7</category><category>iphone xs</category><category>iphone8</category><category>iquiksplash</category><category>itunes</category><category>jobs</category><category>jpg</category><category>keyboard</category><category>lag</category><category>leopard</category><category>levels</category><category>linkshare</category><category>mac osx</category><category>macbook</category><category>make</category><category>manual</category><category>map</category><category>mario</category><category>memory</category><category>method</category><category>methods</category><category>more</category><category>more tab</category><category>mov</category><category>movie</category><category>moving</category><category>mp4</category><category>multiline</category><category>no</category><category>not</category><category>nsurlsession</category><category>numbers</category><category>obj-c</category><category>online</category><category>only</category><category>or</category><category>os3.2</category><category>outline</category><category>overlay</category><category>page</category><category>paint</category><category>particle</category><category>photo</category><category>planning</category><category>platform</category><category>playground</category><category>png</category><category>polish</category><category>populating</category><category>pre</category><category>principles</category><category>process</category><category>profile</category><category>programming</category><category>project</category><category>provisioning</category><category>public</category><category>quartzcore</category><category>redo</category><category>resources</category><category>retina</category><category>retro</category><category>reusables</category><category>royalty free</category><category>safe</category><category>safearea</category><category>safearealayoutguide</category><category>safearelayout</category><category>screencast</category><category>script</category><category>scroll</category><category>scrollview</category><category>seamless</category><category>search</category><category>selector</category><category>setting up</category><category>shine</category><category>simple</category><category>simulator</category><category>single</category><category>singleton</category><category>size</category><category>skspritekit</category><category>skview</category><category>slide</category><category>slrequest</category><category>snow</category><category>solution</category><category>sounds</category><category>speech</category><category>spritesheet</category><category>sso</category><category>stackoverflow</category><category>steps</category><category>steve</category><category>storekit</category><category>storyboard</category><category>subclass</category><category>submission</category><category>swift</category><category>swipe</category><category>swipeable</category><category>switching</category><category>synthesizer</category><category>tableview</category><category>text</category><category>texture</category><category>tile</category><category>tips</category><category>touch</category><category>touches</category><category>twitter</category><category>uicollectionview</category><category>uicontrol</category><category>uiimagepickerview</category><category>uiswitch</category><category>uitableview</category><category>uiview</category><category>uiviewcontroller</category><category>undo</category><category>universal</category><category>unlock</category><category>use</category><category>user</category><category>using</category><category>variable</category><category>variables</category><category>view</category><category>viewcontrollers</category><category>voice</category><category>wall</category><category>way</category><category>weather</category><category>webservice</category><category>wireframe</category><category>wireframing</category><category>x</category><category>xib</category><title>XCode Tutorials for Beginners</title><description>XCode and iOS Tutorial for Newbies with downloadable Source Code!</description><link>http://xcodenoobies.blogspot.com/</link><managingEditor>noreply@blogger.com (GeneCode)</managingEditor><generator>Blogger</generator><openSearch:totalResults>55</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><language>en-us</language><itunes:explicit>no</itunes:explicit><itunes:subtitle>XCode and iOS Tutorial for Newbies with downloadable Source Code!</itunes:subtitle><itunes:owner><itunes:email>noreply@blogger.com</itunes:email></itunes:owner><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-7592009574467546531</guid><pubDate>Fri, 01 Nov 2024 05:18:00 +0000</pubDate><atom:updated>2024-10-31T22:23:09.836-07:00</atom:updated><title>Everything that has a beginning, has an end.</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6ww6X_ngQ32O1mxGfreqleVDKb9r5SKCWi5pxT23cH_GVNH2soVQGWHC3pigpfSyh3Zw9AT37VRvy6x0hx6CZOMjAsXyC7jM9eSw2oqQpAULE54fp3cJq_131mK5fYYn7r8Fvq_GeQnv8C0pt2sTTgB6y7UY3JcT7_6EmHLsltAZORkebQaY94ywZPMg/s400/96b749d9-3268-4274-96ae-62c5ff3470b8_text.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="167" data-original-width="400" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6ww6X_ngQ32O1mxGfreqleVDKb9r5SKCWi5pxT23cH_GVNH2soVQGWHC3pigpfSyh3Zw9AT37VRvy6x0hx6CZOMjAsXyC7jM9eSw2oqQpAULE54fp3cJq_131mK5fYYn7r8Fvq_GeQnv8C0pt2sTTgB6y7UY3JcT7_6EmHLsltAZORkebQaY94ywZPMg/w400-h168/96b749d9-3268-4274-96ae-62c5ff3470b8_text.gif" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2009-2024 is a long time, but I had fun. I have made some 47 apps that was released in the app store during that time. I'd say, in the beginning, the Apple's App Store was a cool place for individual software developers with any ideas. Some crazy ideas, some noble and outstanding ideas, and even stupid ideas, could sell.&lt;/p&gt;&lt;p&gt;In my final blog post as an iOS Indie Developer, I will reminisce my experience as the solo iOS developer through out the 15 years.&lt;/p&gt;&lt;span&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;In 2009, I have just quit a steady job of 8 years at a prestigious audio-video electronics product manufacturing company as an R&amp;amp;D Engineer. The company unfortunately has been suffering financially for a few years, due to the transitioning state of technology.&lt;/p&gt;&lt;p&gt;People no longer are buying Hi-Fis. They no longer appreciate sound quality but instead they are more interested in quality visuals such as LCD and Plasma. As for sound, as long as you have speaker, that's good enough.&lt;/p&gt;&lt;p&gt;So after I quit the job I tried to find other jobs but to no avail. There are bills to pay and family to feed. Then a friend of mine shared a newspaper clip about a boy in Singapore that sold thousands copies of iOS app. I was intrigued and immediately bought a second hand Macbook White to try and develop apps.&lt;/p&gt;&lt;p&gt;At that time, coding resources are not abundant like today. It was a bit hard to learn anything. Back in 2009, I only knew Lazarus/Pascal and simple Bash script. So to learn Objective-C to develop iOS app was a challenge.&lt;/p&gt;&lt;p&gt;Nevertheless, stackoverflow helped and of course THE iOS developer forum back then, the iPhoneDevSDK.com. A lot of us hanging out there were indie developers, and we helped each other where we can. Of course, it was still a competition, so coding help can be a little restricted because we don't want to teach others to be our own app's competitor lol.&lt;/p&gt;&lt;p&gt;The best thing about iOS dev back then in 2009 is the simplicity of XCode. Steve Jobs is a genius for this reason. He made tools that are so easy to use. Install XCode and you're all set to create your first app. There are no dependencies to install, no frequent updates, and simulator works fast and flawlessly.&lt;/p&gt;&lt;p&gt;My first app was iTronixPal. This app is a simple app for Electronics enthusiasts. Things like Resistor color code decoder is useful for people working in the electronics industry, or even for a hobbyist.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFqjy8ZtmDU7EPVRY6c3bDJd1BtonAZDsgPV7NQOxUiJWQPGtj5ZZ9RQh8yOwDtkjGjIQt1_WryWyUrUT2sAxAelIztd7btJV2QJw06s2BYvte07ffTNEBR3i-uQ05juxJGLcmP1aTWd8AhkpW7VMaJ7qA3xfo0ea4wB-UI6YtRSSUuOGk2VdHZzx9Vqk/s368/1.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="368" data-original-width="256" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFqjy8ZtmDU7EPVRY6c3bDJd1BtonAZDsgPV7NQOxUiJWQPGtj5ZZ9RQh8yOwDtkjGjIQt1_WryWyUrUT2sAxAelIztd7btJV2QJw06s2BYvte07ffTNEBR3i-uQ05juxJGLcmP1aTWd8AhkpW7VMaJ7qA3xfo0ea4wB-UI6YtRSSUuOGk2VdHZzx9Vqk/s320/1.jpg" width="223" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOwy2NfDPHNC5gglFUcGUjFQyZt6ZW-clGLwn3E2H8_wAOL40aTYLYKM2s17jSAqfArMdXR5ZTEx7FoGz-tbCdLzdJ-eHcnHq0L1MxeZPpuRgVckZbE2dJBJn_9Q5K1t8CyAK5Xh7bp38APMWOlFeFQWRGfwWAOlVR_tFfB8c9vaBHOjjv8CGl7KylwmE/s368/2.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="368" data-original-width="256" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOwy2NfDPHNC5gglFUcGUjFQyZt6ZW-clGLwn3E2H8_wAOL40aTYLYKM2s17jSAqfArMdXR5ZTEx7FoGz-tbCdLzdJ-eHcnHq0L1MxeZPpuRgVckZbE2dJBJn_9Q5K1t8CyAK5Xh7bp38APMWOlFeFQWRGfwWAOlVR_tFfB8c9vaBHOjjv8CGl7KylwmE/s320/2.jpg" width="223" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA7bgXLsyM4J5SlplSCnp35a4dCwW-9cDFZbzCdmaFbFHVbT477Q3ThdHRsTAJDgY0PiwNi-KhYh1sP5ajtTlxUnLbSV_Jf4rv-i1SCxKptWA7Eoq-1UnqIZp1DxsVc5haW_eTFE6sQRZtG8XHRwfw45C_M0y93evay1x7hOWhYfdSdHIBXP0CR5MvGeM/s368/3.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="368" data-original-width="256" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA7bgXLsyM4J5SlplSCnp35a4dCwW-9cDFZbzCdmaFbFHVbT477Q3ThdHRsTAJDgY0PiwNi-KhYh1sP5ajtTlxUnLbSV_Jf4rv-i1SCxKptWA7Eoq-1UnqIZp1DxsVc5haW_eTFE6sQRZtG8XHRwfw45C_M0y93evay1x7hOWhYfdSdHIBXP0CR5MvGeM/s320/3.jpg" width="223" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;I tried to make it as nice as possible of course, because in iOS, aesthetics is very important. iOS users love pretty things. Back then I used Paint Shop Pro and I didn't know about vector graphics yet. But it works well because iPhones and iPod only have a single form factor.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then I made a second app that change everything, it was iQuikSplash. iQuikSplash is a clone of the Color Splash app. Basically it just highlights a part of a photo and turns the rest to black and white. While the Color Splash app require you to manually draw using your finger the area that you want to leave in color, iQuiksplash did it by auto selection of a color.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBPPUU68F_fNXHjSfmiI-XKtvU53UfzyHtV1Dx_T1l4g52VI_OtieGZFPfOJx7fTxWU25yEpcZs51waxLTy72AU42YScaxDLDvsSg3J31RtMc9QqDk4okvWp4GXMsM6un-CjSNEPNH_ryrwhaNT6rA_UT8dQLKtc2yqroyM-BvwAzRVG8-7Bo6Be7WMFA/s480/T11105167-0.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="480" data-original-width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBPPUU68F_fNXHjSfmiI-XKtvU53UfzyHtV1Dx_T1l4g52VI_OtieGZFPfOJx7fTxWU25yEpcZs51waxLTy72AU42YScaxDLDvsSg3J31RtMc9QqDk4okvWp4GXMsM6un-CjSNEPNH_ryrwhaNT6rA_UT8dQLKtc2yqroyM-BvwAzRVG8-7Bo6Be7WMFA/s16000/T11105167-0.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;So, by sheer luck, the Apple's App Reviewer (aka the App Store app curator) thought this was brilliant and my app was featured in the US App Store as New &amp;amp; Noteworthy. The downside was, the app was free and I was scared that if I change the app to Paid, i'd get removed from the New &amp;amp; Noteworthy section. That was a big facepalm by me, otherwise I could have earned a lot of money.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All the while the app was in New &amp;amp; Noteworthy, I left it as free, furthermore I even have the "FREE" word on the icon. Back then, Apple was so strict, one bad move by developer, your app could be rejected and removed from Sale, so that came into play why I left it as free.&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While the free app was getting about 120,000 downloads a day and reaching No.2 spot in the Top Free Photography, I created another app - iQuiksplash Pro and later add the Link to Pro version in the Lite version and that translated to some good profits. I then created more camera apps like AppliFX. A photo app with many filters to apply to your photos.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgHzS2NYBPeBOM4vapb_oNJHnGUIzXdJahhwEKCBGCxBdihZLBwjm6gjUNhxNlvFRC3mj_Wq-XrEjT6kKN-3yI6ul709u-Lji7kvB7dqR5NDGQllbZxWOx7QHR-eyyjUNQ9l0wUb16suO15G26wNH1UKJp5wrHfFreZ1-nswz2SGSyWdFjYhrP8093dUY/s480/AppliFX.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="480" data-original-width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgHzS2NYBPeBOM4vapb_oNJHnGUIzXdJahhwEKCBGCxBdihZLBwjm6gjUNhxNlvFRC3mj_Wq-XrEjT6kKN-3yI6ul709u-Lji7kvB7dqR5NDGQllbZxWOx7QHR-eyyjUNQ9l0wUb16suO15G26wNH1UKJp5wrHfFreZ1-nswz2SGSyWdFjYhrP8093dUY/s16000/AppliFX.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The app gained quite a good downloads as well and it was a paid app. But, it crashes a lot because I was developing on SIMULATOR!! I made the mistake of taking the photos as is and processing the pixels in memory, and in large photos, the phone became out of memory and crashes the app. Then, I had no choice but to buy an iPod Touch. I get to fix most of the issues and the sales continue on.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I was getting good sales for these apps, as I created more apps, then Steve Jobs died. If you remember, this was the time iOS became ugly as f-ck! iOS5 and below, that was awesome, but iOS6 with its fugly flat design make me wanna puke! Then sometime in 2012, Apple acquired Chomp, a search engine company, to be implemented into App Store. That was when I noticed a considerable drop in my app discovery and sales. It focuses on App Title, Description and Ratings, and not just keywords. I tried to search my own app name "iQuikSplash" and it did not come up top anymore. So how are people who read about my app elsewhere could find my app?&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;That was the time where fake ratings and fake review started to show on my apps. You can click on a rating and see what other apps the user rate, and it is so obvious that a person rates 1 stars for all Photo apps, but only 1 app is getting 5 stars. Such scam turns the App Store into a savage, dog eat dog marketing world.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;It was heartbreaking. As the years go by, more and more established and big corporations joined in the App Store in publishing even more professional apps, and not only that, they can also afford super expensive marketing campaign, that in turn, bury most of us indie developers, who only make enough for a living.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I tried to hang on from 2012 to 2015, sold some assets to keep afloat, and by end of 2015 I realized the Indie Dream is dead. So I started to find a day job as iOS developer in a company. It was ok but it was no longer fun making apps for other people. I quit that too and now I work in Industrial IT sector which I find is rewarding. Occasionally I get to code too, so that's a plus.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;So that's all I have to share about my experience as an Indie iOS developer. I think Apple needed Steve Jobs, but as he dies, so does Apple. Since then I no longer see the confidence in their products. Stupid decisions are made, like charging port of Magic Mouse placed at the bottom, and latest, power button of Mac Mini placed at the bottom as well. I know Jobs will never allow that to happen.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, as Agent Smith said, Everything that has a beginning, has an end.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Finally, shout out to fellow indie devs who helped and just by being there over in the iPhoneDevSdk forum.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Adios.&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</description><link>http://xcodenoobies.blogspot.com/2024/10/everything-that-has-beginning-has-end.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6ww6X_ngQ32O1mxGfreqleVDKb9r5SKCWi5pxT23cH_GVNH2soVQGWHC3pigpfSyh3Zw9AT37VRvy6x0hx6CZOMjAsXyC7jM9eSw2oqQpAULE54fp3cJq_131mK5fYYn7r8Fvq_GeQnv8C0pt2sTTgB6y7UY3JcT7_6EmHLsltAZORkebQaY94ywZPMg/s72-w400-h168-c/96b749d9-3268-4274-96ae-62c5ff3470b8_text.gif" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-1132713423969646030</guid><pubDate>Thu, 20 Aug 2020 09:59:00 +0000</pubDate><atom:updated>2020-09-19T20:59:57.611-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">automation</category><category domain="http://www.blogger.com/atom/ns#">command lines</category><category domain="http://www.blogger.com/atom/ns#">development</category><category domain="http://www.blogger.com/atom/ns#">inkscape</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">mac osx</category><category domain="http://www.blogger.com/atom/ns#">script</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><title>How To: Automation Export PNG in Inkscape V1.0</title><description>&lt;div&gt;What's up?&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_zTF3RS2rZlCB5zvU3c3JBTRcm3kOsdJBqwjbcVq_j5fsbbaWthVniq6ngNT-ILu1P-ozY9Xjkqak0BzTIJpf2DYu3DAOaSR0-eTEFYQ4Jc_MD5veAv5TfBkdlCZrBc-pSarQki5YXcs/s500/BoringUnselfishConch-size_restricted.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="262" data-original-width="500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_zTF3RS2rZlCB5zvU3c3JBTRcm3kOsdJBqwjbcVq_j5fsbbaWthVniq6ngNT-ILu1P-ozY9Xjkqak0BzTIJpf2DYu3DAOaSR0-eTEFYQ4Jc_MD5veAv5TfBkdlCZrBc-pSarQki5YXcs/s0/BoringUnselfishConch-size_restricted.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Been a while eh? Everyone is doing well avoiding Covid19 I see. To the fallen ones, RIP. Nobody lives forever. Those that goes on, keep up keeping up.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Today I will be posting about how we can automate Inkscape export. I.. have...been.. doing... stupid... things.... for... 10 years. *SMACK HEAD*. Aw come on, everyone does stupid thing once in a while. Nobody is holy. What I mean, is for 10 years or more since I used Inkscape I have exported PNG for use in iOS apps this way:&lt;/div&gt;&lt;span&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjkmObo0UBveg2zYclChN9-c_0f4uGhhRsLzkCPYA7yQAzv7eEXPfc9ZuJP0LlTL-VQ4XzTm4_xk1B8TcIFVWLFlSEGN_RT33QHANVuFlwIvdN5edKeP2YK_zg15LLSniOO30js4elhZE/s924/Aug-20-2020+16-50-42.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="524" data-original-width="924" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjkmObo0UBveg2zYclChN9-c_0f4uGhhRsLzkCPYA7yQAzv7eEXPfc9ZuJP0LlTL-VQ4XzTm4_xk1B8TcIFVWLFlSEGN_RT33QHANVuFlwIvdN5edKeP2YK_zg15LLSniOO30js4elhZE/s640/Aug-20-2020+16-50-42.gif" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's a 18MB GIF File. :P&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Enough to illustrate the amounts of keyboard presses and mouse clicks just to save @1x, @2x, @3x PNG of a particular image! Crazy!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Enter the Inkscape 1.0 Command line!&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Inkscape has been Beta for a long while. And recently they (WHO IS 'THEY'?????), released a V1.0. With it, comes awesomeness and pizzas. Ok kidding about the pizza. But dark mode, and the fact that it no longer requires X11 to run tastes like pizza really. So good. Even in Beta, command lines exist, but there are not much tutorials about it. Especially on Mac.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I had some time to tinker with it, and managed to make it work after 3-4 hours.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The command line works with the inkscape binary that resides INSIDE the Inkscape.app package that resides in /Application/ folder. As MacOS uses linux base, we can write a simple bash script to automate the export of a particular object groups.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are requirements to implement this:&lt;/div&gt;&lt;div&gt;&lt;ol style="text-align: left;"&gt;&lt;blockquote&gt;&lt;li&gt;You need to know your way around the Terminal app, and linux basic command lines like cd, ls, etc.&lt;/li&gt;&lt;li&gt;You need to specify FULL PATHS to input SVG and output PNG, otherwise the binary is going to assume it exist in current directory.&lt;/li&gt;&lt;li&gt;You need a code text editor like Atom. But, you can also use TextEdit, but the syntax will not be highlighted in pretty colors. :P&lt;/li&gt;&lt;li&gt;In the SVG, you need to give "ID" to the objects that you grouped to be exported.&lt;/li&gt;&lt;/blockquote&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;For this tutorial, I will setup a script that resides in your home user directory. For me it is&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: courier;"&gt;/Users/genecode&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So in this folder, I shall create another folder for svg file.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: courier;"&gt;/Users/genecode/svg&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then we will output the PNG in another folder.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: courier;"&gt;/Users/genecode/output&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfirzcA0LnJCMkNLogLMw2QbB0sYGCJHLaMkjPSy-rKj-fLfDpU5IvRyWCSOrhevLxU2K7gTo-QcGGp7h8oUwqbOzqPoVX_lsI4frgiTw-3fQ16iaRuSnwe4qzjqGVPm1tXNWEF3DpBAo/s715/folders.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="185" data-original-width="715" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfirzcA0LnJCMkNLogLMw2QbB0sYGCJHLaMkjPSy-rKj-fLfDpU5IvRyWCSOrhevLxU2K7gTo-QcGGp7h8oUwqbOzqPoVX_lsI4frgiTw-3fQ16iaRuSnwe4qzjqGVPm1tXNWEF3DpBAo/s640/folders.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now lets create the SVG file. I made this car with tyres in inkscape. All are in same layer. For this to work, it does not matter which layer the object resides. What matters is what unique ID you gave them.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxDd0qlpS5T4AWEoZbJBDN8fJ8RiMvLH-rGU7KJgtxbvxslnIy_qbsP0_CtcKNojZoQC10fGPNze3-2kVSjyC5rMddwiCYanLw8CEJ2ArVWMs3gRs4MbBYbcVa6gzUZYzU67eQmftM8io/s624/svg.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="417" data-original-width="624" height="267" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxDd0qlpS5T4AWEoZbJBDN8fJ8RiMvLH-rGU7KJgtxbvxslnIy_qbsP0_CtcKNojZoQC10fGPNze3-2kVSjyC5rMddwiCYanLw8CEJ2ArVWMs3gRs4MbBYbcVa6gzUZYzU67eQmftM8io/w399-h267/svg.png" width="399" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;(My awesome artwork :P)&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Lets assume you want to export the car body into carBody@1x,@2x,@3x and carTyre@1x,@2x,@3x. Notice that the body is just one object created with Pen tool. And that each of the tyre is 2 objects (black and grey circles).&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Before saving the svg, click the body, right click and select "Object Properties" on the menu. Then on "ID", enter "bodyID" for example. Then click "Set" button. (ID can be anything you choose). Do the same with one tyre, group the tyre into one group, and right click and select "Object Properties". on ID, enter "tyreID".&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYKTGI1OPj7gmAeFxmWVJvCK5sn4KLzlxe_OinFXFPM6QKnUB1ERMHXaIUApmPTUIUlXcWxxYsiWRi60Vzuy7Qi2uH2KGzhTpuQ9R0_xKQBDjFlofazlkQI1KWZPNq7wswwEHYvyjIxmo/s725/ID.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="548" data-original-width="725" height="388" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYKTGI1OPj7gmAeFxmWVJvCK5sn4KLzlxe_OinFXFPM6QKnUB1ERMHXaIUApmPTUIUlXcWxxYsiWRi60Vzuy7Qi2uH2KGzhTpuQ9R0_xKQBDjFlofazlkQI1KWZPNq7wswwEHYvyjIxmo/w513-h388/ID.png" width="513" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Once that done, save your drawing.svg in the /User/genecode/svg/ folder , and open your code editor.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;First, I decided that I want to be able to give the automation script a parameter input of the svg filename. Something like&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: courier;"&gt;sh export.sh drawing&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;This enables me to export from any svg that I want. Here is the script that I came up with, that complies to the folders that we created earlier:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;for i in {1..3}
do

  WID=$((600*i))
  /Applications/Inkscape2.app/Contents/MacOS/inkscape --export-type="png" --export-id="bodyID" --export-id-only --export-filename="carBody@${i}x.png" --export-background-opacity=0 --export-width=$WID  $(pwd)/svg/$1.svg

done
&lt;/code&gt;&lt;/pre&gt;
&lt;div style="text-align: left;"&gt;The inkscape command line starts at /Applications/Inkscape2.app... The rest are bash.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;b&gt;What does the code do?&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;for i in {1..3}&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;WID=$((600*i))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;First, this will loop the command line 3 times to produce @1x.png, @2x.png and @3x.png in one go. I also has a formula to automatically calculate the width of each PNG in each passes. First will be 600, second 1200, and third 1800 pixels.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;/Applications/Inkscape2.app/Contents/MacOS/inkscape&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Also to note, that my Inkscape is named Inkscape2 in Applications, hence my path points to that. That is because I still have the beta version inkscape as "Inkscape" in Applications. So you need to change yours to be Inkscape.app if you do not name it differently.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;--export-type="png"&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;This will tell inkscape to output PNG files.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;--export-id="bodyID"&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;div&gt;This will tell inkscape to export only the objects with group ID "bodyID" as we set in Object Properties above.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;--export-id-only&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;This will tell inkscape to object with export ID only.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;--export-filename="$(pwd)/output/carBody@${i}x.png"&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;This will tell what filename the exported PNG will have. Here I put in variable names based on the loop variable. This will match to iOS app standard. pwd is a standard unix command to get (p)arent (w)orking (d)irectory. Since the script resides in /Users/genecode, this line will translate to /Users/genecode/output/carBody**.png&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;--export-background-opacity=0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;This will tell inkscape to export with transparent background.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;--export-width=$WID&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;This will specify the width of PNG to export.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code class="obj-C"&gt;$(pwd)/svg/$1.svg&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;And finally this is the input SVG file that are input by parameter as we've decided. pwd is a standard unix command to get (p)arent (w)orking (d)irectory. Since the script resides in /Users/genecode, this line will translate to /Users/genecode/svg/drawing.svg&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;GREAT! EASY RIGHT?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now lets see the script in action:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieYhvpLURJKX1fFTLk-w5lJUjZ57Rrz1yp-xhl8LHUigh7L5KjywDlPaUBMoOiNgGKzj94Bsf819tITr3Tqf17693hdSTal5V9wQ5HsoFrya8Z9utX3G4uiH283ku1NeOVPlAeBaZz1mo/s594/exportScript.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="594" data-original-width="588" height="475" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieYhvpLURJKX1fFTLk-w5lJUjZ57Rrz1yp-xhl8LHUigh7L5KjywDlPaUBMoOiNgGKzj94Bsf819tITr3Tqf17693hdSTal5V9wQ5HsoFrya8Z9utX3G4uiH283ku1NeOVPlAeBaZz1mo/w470-h475/exportScript.gif" width="470" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As you can see, 3 images of the carbody are exported to the output folder on the go. You can then add more lines in that for loop to add more objects to be exported automatically.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are the results:&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2-IT7LpCFBWpbaY3raVBGqiq2ecI-oahfg4RMN58ZAeinQIANki_uP7xudzplLGovkE7gf-S1q2wpjfYJyV1CWXTYlnKGndF9wnTi8bLYn8gM_qU4pPe0YW9CZhQ19umJQiqgpHQxGLo/s646/car.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="375" data-original-width="646" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2-IT7LpCFBWpbaY3raVBGqiq2ecI-oahfg4RMN58ZAeinQIANki_uP7xudzplLGovkE7gf-S1q2wpjfYJyV1CWXTYlnKGndF9wnTi8bLYn8gM_qU4pPe0YW9CZhQ19umJQiqgpHQxGLo/w512-h298/car.png" width="512" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This will surely save your time! Ok thanks for reading. Cheerio.&lt;/div&gt;&lt;/div&gt;</description><link>http://xcodenoobies.blogspot.com/2020/08/how-to-automation-export-png-in.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_zTF3RS2rZlCB5zvU3c3JBTRcm3kOsdJBqwjbcVq_j5fsbbaWthVniq6ngNT-ILu1P-ozY9Xjkqak0BzTIJpf2DYu3DAOaSR0-eTEFYQ4Jc_MD5veAv5TfBkdlCZrBc-pSarQki5YXcs/s72-c/BoringUnselfishConch-size_restricted.gif" width="72"/><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-2024406182377357122</guid><pubDate>Sat, 28 Mar 2020 08:45:00 +0000</pubDate><atom:updated>2020-03-28T01:51:20.751-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">apps</category><category domain="http://www.blogger.com/atom/ns#">design</category><category domain="http://www.blogger.com/atom/ns#">guidelines</category><category domain="http://www.blogger.com/atom/ns#">how to</category><category domain="http://www.blogger.com/atom/ns#">human</category><category domain="http://www.blogger.com/atom/ns#">interface</category><category domain="http://www.blogger.com/atom/ns#">jobs</category><category domain="http://www.blogger.com/atom/ns#">principles</category><category domain="http://www.blogger.com/atom/ns#">steve</category><title>How To: Apply Steve Jobs Design Principle in Your Apps</title><description>&lt;b&gt;&lt;u&gt;Introduction&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Today, I want to write about a crucial topic in app development - software design. It is based on my own experience developing and designing softwares since 1990s. But let me indicate here that I do not have ANY computer subjects qualifications. I do not know a lot of computing terms, jargons, methodologies and I am not even well versed in deployment process, staging, unit tests, CID, blah blah yadda yadda. I was an Electrical &amp;amp; Electronics Engineering Major. But I have always find software development interesting and fun. To create something that people use and benefit from. But I think it is mostly due to the no-bullshit work environment. You cannot lie to your computer. And your computer cannot lie to you. If you input a = 1; There is no way in hell, your computer would say a = 2; Unless you told the computer to add a 1 to it. The honesty with coding, is satisfying.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
There are grey areas though. Especially happens when you do not understand the code you are writing. For example, a global variable that is non exclusive, and has multiple threads accessing it, and you are using that variable to do something else, an unexpected result may occur. But the unexpected result occurred by truth. And not by lies. So, if you traverse the thread, slowly, you will be able to see the problem and pin point the cause.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;Steve Jobs's Design Principle&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjtvf75WooGmdrV6k5Ah9fAHKhhDv8SIMLdu_glhjelGIgEPBcmHlvlb6Ks2A_j-_YfUyK7tppS2J6DTfOSfBjeio9aysb2hurLIl4yFiy3SUu_IhxLtYQJuh84WmdAEBbYUND2WpCv5M/s1600/Steve+Jobs+Quote+And+Saying+Design+Is+Not+Just+What+It+Looks+Like+And+Feels+Like.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="420" data-original-width="800" height="336" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjtvf75WooGmdrV6k5Ah9fAHKhhDv8SIMLdu_glhjelGIgEPBcmHlvlb6Ks2A_j-_YfUyK7tppS2J6DTfOSfBjeio9aysb2hurLIl4yFiy3SUu_IhxLtYQJuh84WmdAEBbYUND2WpCv5M/s640/Steve+Jobs+Quote+And+Saying+Design+Is+Not+Just+What+It+Looks+Like+And+Feels+Like.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;Some people calls Apple fans as &lt;b&gt;sheeple&lt;/b&gt;&amp;nbsp;&#128017;- dumb sheep that just support Apple whatever they do. I guess, that would be true for any groups of people. There are those who see and acknowledge the truth in a system. And there are those, who follow blindly. As for me, I'd like to believe that I saw the genius in Apple (back when Jobs was still alive anyways). What makes Apple great, was how intricate the consideration in designing every single little things, and how all of them have connections to user ability by human beings. Hence why the Apple's User guidelines were dubbed the "&lt;b&gt;Human Interface Guidelines&lt;/b&gt;". There are plenty of extremely important guidelines in there. A traditional software may have a User Manual. But Apple's softwares shall have a Human Manuals. A reminder that the users are actual human beings with feelings, limbs and eyes.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
An example of Jobs' genius,&amp;nbsp; is in the simplicity of the OS, namely iOS. Back then, the iOS is so simple, that using the limited iOS fits well in the small device that we carry on our hands. Thus we are more focused in doing work rather than wasting time to figure out how to enable a feature.&lt;br /&gt;
There are so many other genius ideas, like gestures, magnetic power port, positioning of power button and volume buttons accessible easily by the thumb, and so on.&lt;br /&gt;
&lt;br /&gt;
Traditional developers often work from codes, to peripherals, to hands and fingers that use them. They prioritize code simplicity and focused on functionality 100%. Apple developers, are taught to work from their bodies, to their hands, fingers, eyes, to peripherals and finally the code and functionality. It is at 180 degrees from what traditional developers do. And that is why it was able to capture so many people by heart.&lt;br /&gt;
&lt;br /&gt;
To visualize and therefore prove the definition of this "&lt;i&gt;reversed approach&lt;/i&gt;", lets take a simple data collection represented by a UITableView. I will take my latest app under development as an example, Cars.tomizer:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbgFUsBdzO2sn7m-P2qQA92DLeBxbQzYGshPG6R_B3Vx0NrDAqDoj-nR-M0H74A4REBo_1pykK_YtQRTPOaabqT7q6uTpXn0tznnNsqTfsZ1znvSVOmKJL45_sO5ARg4QDwV6fLnL1EBQ/s1600/Simulator+Screen+Shot+-+iPhone+8+-+2020-03-28+at+15.36.53.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="750" data-original-width="1334" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbgFUsBdzO2sn7m-P2qQA92DLeBxbQzYGshPG6R_B3Vx0NrDAqDoj-nR-M0H74A4REBo_1pykK_YtQRTPOaabqT7q6uTpXn0tznnNsqTfsZ1znvSVOmKJL45_sO5ARg4QDwV6fLnL1EBQ/s320/Simulator+Screen+Shot+-+iPhone+8+-+2020-03-28+at+15.36.53.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Looks good? Job well done? Take a look again. What is the problem? Let me list down the issue with this design. It appears that there are only 3 cars here. The scrollbar for UITableView is hidden. So it is not immediately obvious that you can scroll for more. How do we apply the Jobs' Design Principle here? Many ways:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1&lt;/b&gt;. Add shadow to the bottom bar, so it appears that the list is behind the bar, and human will guess there are more.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcC06pkgjH9LVZ22JkCCsEqXt8qeNNz-liw3eMezAKktBJ0h1wtk0NhYO2PhIb2Iat3H02iA8S_7dIYZ3_2CeR_CcmC8Rr5-KZxjpp8fBQyOTE0oHHE6ObGmCjZ9zKL67_1rMhFGKzFqQ/s1600/Simulator+Screen+Shot+-+iPhone+8+-+2020-03-28+at+15.41.41.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="750" data-original-width="1334" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcC06pkgjH9LVZ22JkCCsEqXt8qeNNz-liw3eMezAKktBJ0h1wtk0NhYO2PhIb2Iat3H02iA8S_7dIYZ3_2CeR_CcmC8Rr5-KZxjpp8fBQyOTE0oHHE6ObGmCjZ9zKL67_1rMhFGKzFqQ/s320/Simulator+Screen+Shot+-+iPhone+8+-+2020-03-28+at+15.41.41.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Better right?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2&lt;/b&gt;. Alternatively, adjust the cell height, so that the default view cuts off half of the third car, implying, there are more down there. Or combine both:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrRl8pPhtgiEfhi0Ee0hoNoFK7KTWh5EUve8_YILZBJrtQjWDbzf87afgWRg570I-mQ-yR2SADxUJhTMCXHU_7zeU9v_TlLqjNPNHOIzB2SsMdKhAY82Ck1GpHgCgr7XS7HO8sF0MC2WE/s1600/Simulator+Screen+Shot+-+iPhone+8+-+2020-03-28+at+15.44.27.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="750" data-original-width="1334" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrRl8pPhtgiEfhi0Ee0hoNoFK7KTWh5EUve8_YILZBJrtQjWDbzf87afgWRg570I-mQ-yR2SADxUJhTMCXHU_7zeU9v_TlLqjNPNHOIzB2SsMdKhAY82Ck1GpHgCgr7XS7HO8sF0MC2WE/s320/Simulator+Screen+Shot+-+iPhone+8+-+2020-03-28+at+15.44.27.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Now it is even more obvious that this data is scrollable, and there are more down there.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3&lt;/b&gt;. Go a little bit further - add a tiny scrolling animation upon opening the view.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbEdxgpRm2MJKw-sly4zBrbGeHyLWbTjigU9qqbNbrIO3fBh1rh8sbc_N145jOECS8UUg8p50f_VRPOfT6yyV_bZm9W_o-R0OSXu29uN-i4w45xAeihT6Mb0LKIJ0apikHkH1zVc7IlxA/s1600/Mar-28-2020+15-47-39.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="552" data-original-width="990" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbEdxgpRm2MJKw-sly4zBrbGeHyLWbTjigU9qqbNbrIO3fBh1rh8sbc_N145jOECS8UUg8p50f_VRPOfT6yyV_bZm9W_o-R0OSXu29uN-i4w45xAeihT6Mb0LKIJ0apikHkH1zVc7IlxA/s320/Mar-28-2020+15-47-39.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
4. You can think of any other ways to achieve this. These are just examples of the extra considerations in order to apply Jobs' Design principle.&lt;br /&gt;
&lt;br /&gt;
Most traditional developers will stop at the first step. Their mindset is stuck at the functionality, and as far as functionality is concerned, their job is done. And that is where they are wrong. This case is just one example of the Design Principle taught by Steve Jobs. Go the extra mile to make every little things, work and present themselves in the best way.&lt;br /&gt;
&lt;br /&gt;
And when you start applying these principles, you will find your users, easily figure out things in your apps, and that makes them happy. Their workflow improved greatly, and hopefully that 4 or 5 Stars are coming in.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;Testing Your Apps&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
Once your app is done, as developer or programmer, you often cannot be bothered to really test your app. You are tired and exhausted from coding. So having a beta test team is critical. Their job is to scrutinize your work. Condemn it to hell. And complain for every tiny thing that bothers them. And developer MUST fix all of them.&lt;br /&gt;
&lt;br /&gt;
As for me, a solo indie hobbyist developer, I often simply give it to my kids to test. If even a kid can't figure out how things work, it is a clear indicator that your app design is problematic. And what's more important is for you to SEE the app in action used by another person. See how they interact with it. Which button do they press first, and so on.&lt;br /&gt;
&lt;br /&gt;
Stress test is also important. If you app involves saving data into the phone, add up as much data as possible and try saving and loading repeatedly. Make sure the app does not crash. These are typical test procedures, on the surface. If you wish you could go deeper by testing your app using Intruments or Profiling tool in XCode. I have not really used them though. I rely on good old user test methods.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;Summary&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
As a summary, what I can say about Jobs' Design Principle is - your job as developer does not stop at functionality. Go the extra mile, with human interaction considerations. Add that 5 or 10 more methods, 500 lines of codes or more, to polish the app, so it is easy to use, easy to recognize, that essentially, your ultimate aim is to the point that the user won't even need to "Read Instructions". And particularly, HOW a particular feature works. Does it also involve way too many steps to achieve a simple job? Eliminate steps, eliminate button presses. Use gestures, but don't overuse them. It will be hard to make things simple, as Jobs' said:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY_pzyXK4vsz7DVVy-sykNb5qQkCykvMATQRRRr-IJJuYz1ppc8JHWKUWBzAqAUM9no4Utd2SHQjZMC-Zhd5dLoNDULRubvZ2Ltx7zx0NdgIP2dK5ir_GW_TYDpYgqgDR4rkbQ7HXN9U4/s1600/Steve-Jobs-Quotes-13.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="550" data-original-width="500" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY_pzyXK4vsz7DVVy-sykNb5qQkCykvMATQRRRr-IJJuYz1ppc8JHWKUWBzAqAUM9no4Utd2SHQjZMC-Zhd5dLoNDULRubvZ2Ltx7zx0NdgIP2dK5ir_GW_TYDpYgqgDR4rkbQ7HXN9U4/s320/Steve-Jobs-Quotes-13.jpg" width="290" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Go the extra mile and happy coding!&lt;/div&gt;
</description><link>http://xcodenoobies.blogspot.com/2020/03/how-to-applying-steve-jobs-design.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjtvf75WooGmdrV6k5Ah9fAHKhhDv8SIMLdu_glhjelGIgEPBcmHlvlb6Ks2A_j-_YfUyK7tppS2J6DTfOSfBjeio9aysb2hurLIl4yFiy3SUu_IhxLtYQJuh84WmdAEBbYUND2WpCv5M/s72-c/Steve+Jobs+Quote+And+Saying+Design+Is+Not+Just+What+It+Looks+Like+And+Feels+Like.jpg" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-4757162078578337004</guid><pubDate>Tue, 31 Dec 2019 11:22:00 +0000</pubDate><atom:updated>2020-01-07T06:40:09.959-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">basic</category><category domain="http://www.blogger.com/atom/ns#">beginner</category><category domain="http://www.blogger.com/atom/ns#">easy</category><category domain="http://www.blogger.com/atom/ns#">game</category><category domain="http://www.blogger.com/atom/ns#">mario</category><category domain="http://www.blogger.com/atom/ns#">objective c</category><category domain="http://www.blogger.com/atom/ns#">platform</category><category domain="http://www.blogger.com/atom/ns#">Spritekit</category><category domain="http://www.blogger.com/atom/ns#">tutorial</category><title>Tutorial: Making a Platform Game Like Mario With SpriteKit (Part 1 - The Basics)</title><description>Another year is gone. I remember when I was a little boy, I'd be hyped when people talk about the "FUTURE". That time, circa 1980s, the "FUTURE" means anywhere in the year 2000+. The year 2020 is somewhat special though due to its nice number arrangement. 2020 itself sounds futuristic. But lo and behold, we are almost there now! 40 years have passed just like that. I have to admit when you reach 40, time seems to go by much more faster. It seems you have so much to do, but there isn't just enough time to do it. Get busy living, get busy dying.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhayurdvRe4VQsDD9AFcRKF2uonIjWNBmyeQFiieExdLndmtZRRSZFmPN22qWx0uQweriVyUrEDFVRnQYMq6OlhmtFq89L3wc81_IijCAPgDpSwFY8PdIU_0cSl_to0w9IIz0H1mTEC6Wo/s1600/tandy-8499.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="727" data-original-width="562" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhayurdvRe4VQsDD9AFcRKF2uonIjWNBmyeQFiieExdLndmtZRRSZFmPN22qWx0uQweriVyUrEDFVRnQYMq6OlhmtFq89L3wc81_IijCAPgDpSwFY8PdIU_0cSl_to0w9IIz0H1mTEC6Wo/s320/tandy-8499.jpg" width="247" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
20MHz Processor LMAO. 8 Grand&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;a href="https://www.dropbox.com/s/hgmrgj2zo3tgxdb/BunnyPart1.zip?dl=0"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJxG0OiR4I5cgBN5SVtYoQvK4JjHyT-EsRjiDs6Mu8MH_mPgcSoDbpQmPK6jn8bpdTw9vdrj_QZ24_lqOwr8DvRqS-s7KRYw1egiWp1QcukVoy7tu3bEdU1myqnW_nrXXm7gdhunCWdy8/s320/download.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
In terms of tech, no doubt we have progressed so much. Imagine back then in 1980 a computer with very low specs are so expensive. In terms of computing power, and computing tools like Machine Learning, AI, OCR, and so on we have made quite the leap. Imagine what engineers and scientists could achieve in another 40 years? Most probably I'd be dead by then :P&lt;br /&gt;
&lt;br /&gt;
Done with the intro. So, the first ever game I created from scratch &lt;b&gt;with SpriteKit&lt;/b&gt; was the Flappy Bird clone called "Idiot Bird". It was quite a challenge, because I was new to SpriteKit, and Idiot Bird uses physics in order for the bird to fly. And who could forget the way the bird smash its face flat to the ground? Haha...&lt;br /&gt;
&lt;br /&gt;
Believe it or not, my first game I developed in iOS was using 100% &lt;b&gt;UIKit&lt;/b&gt; using UIImageView as sprites. Here take a look:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8v3Ko0gpufGhD-QecYn3t5hWWLZwKivUHmlHLJwgLJcBWSq92aO97lXN-yL2VndfCBVi8F8MBSXTqvxBt4EfcQNkUjbMIgtG8hp9de51B8fG2ILkMRPKh7bnucOJE-Dlr2g0VheGaKOY/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="334" data-original-width="490" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8v3Ko0gpufGhD-QecYn3t5hWWLZwKivUHmlHLJwgLJcBWSq92aO97lXN-yL2VndfCBVi8F8MBSXTqvxBt4EfcQNkUjbMIgtG8hp9de51B8fG2ILkMRPKh7bnucOJE-Dlr2g0VheGaKOY/s320/Untitled.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
I used Paint Shop Pro to create all the (nasty nasty raster) graphics and place them using UIImageViews. It worked quite OK, because it was a turned based game. And animation is smooth just by using a normal UIView animation. This is a monumental evidence that UIKit is such a great framework. Windows framework fails miserably if you try to animate their buttons. There is no fluidity.&lt;br /&gt;
&lt;br /&gt;
Anyway, lets get to topic: SpriteKit's Physics. You can create a Spritekit game without any physics setup. But the kind of games you can make is therefore limited. Games that won't use physics are like Chess game, or card game, or even simple shooting game (top view typically). But if you wish to make a game that feels real, Physics is a must.&lt;br /&gt;
&lt;br /&gt;
For this purpose, we will create a simple scene. A character bouncing on a platform. The first thing to do is to add 2 sprites to a scene. With my amazing graphics skills (lol), here is what I created:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguMQff3M3gp9UzXIR6x2bXQ1DrxlZB3kl2lcRVCkVV3GzwoW-w8VZnfMEqcFE2hZ8QTp4dBSYn1njd89cThvymIwugAu_g3o7YXqDZHcZWtc98kkxQyGgq2pV4BvdbAuOq2TnC_qErsUk/s1600/bunny%25403x.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="183" data-original-width="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguMQff3M3gp9UzXIR6x2bXQ1DrxlZB3kl2lcRVCkVV3GzwoW-w8VZnfMEqcFE2hZ8QTp4dBSYn1njd89cThvymIwugAu_g3o7YXqDZHcZWtc98kkxQyGgq2pV4BvdbAuOq2TnC_qErsUk/s1600/bunny%25403x.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiND0o0QvVVfKF909DmU-BoCRtwGqEAbeiJ1CAcEnxHffdoEBRltYwdixvZCoywb4BzpHWRjrnzz3IX68tT8p_GUcgHq9uXKm958U2f9S7bckDqpUXZDHh2gxvmBUKWEIlIYgFwEwOFFBI/s1600/p_grass%25403x.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="81" data-original-width="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiND0o0QvVVfKF909DmU-BoCRtwGqEAbeiJ1CAcEnxHffdoEBRltYwdixvZCoywb4BzpHWRjrnzz3IX68tT8p_GUcgHq9uXKm958U2f9S7bckDqpUXZDHh2gxvmBUKWEIlIYgFwEwOFFBI/s1600/p_grass%25403x.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You may download the image and resize it for other scales. Add both sprites to the scene in didMoveToView and position the character slightly above the platform.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
- (void)didMoveToView:(SKView *)view {
    
    //create bunny
    SKSpriteNode *bunny = [SKSpriteNode spriteNodeWithImageNamed:@"bunny"];
    bunny.name = @"bunny";
    bunny.position = CGPointMake(self.size.width/2.0, self.size.height/2.0+100);
    [self addChild:bunny];

    //create platform
    SKSpriteNode *platform = [SKSpriteNode spriteNodeWithImageNamed:@"p_grass"];
    platform.name = @"p_grass";
    platform.position = CGPointMake(self.size.width/2.0, self.size.height/2.0);
    [self addChild:platform];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Run it, and you will see both of them in the scene.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNBX0wZQKgRVJEFg8BKtQ_UAwtbTow5LdAN8vgvo_pNJTanVSbdg8NlpP1FbXbJtAQYxQAf2BhBkDnVkmXKQah1Unqqs9KC84vNuD_Ht7-oE7MQTPUsV29yjxcDN5INZuDft6tnWp3GeA/s1600/sprite.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="849" data-original-width="478" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNBX0wZQKgRVJEFg8BKtQ_UAwtbTow5LdAN8vgvo_pNJTanVSbdg8NlpP1FbXbJtAQYxQAf2BhBkDnVkmXKQah1Unqqs9KC84vNuD_Ht7-oE7MQTPUsV29yjxcDN5INZuDft6tnWp3GeA/s320/sprite.png" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
But... nothing happens. Boring right? So how do we tell the scene that we want to apply gravity to the sprites in the scene so that the bunny would fall? Easy. Enter the codes below:&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
    // scene physics initialization
    self.physicsWorld.gravity = CGVectorMake(0, -5.0f);
    
    //create bunny
    SKSpriteNode *bunny = [SKSpriteNode spriteNodeWithImageNamed:@"bunny"];
    bunny.name = @"bunny";
    bunny.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bunny.size]; 
    bunny.position = CGPointMake(self.size.width/2.0, self.size.height/2.0+100);
    [self addChild:bunny];

    SKSpriteNode *platform = [SKSpriteNode spriteNodeWithImageNamed:@"p_grass"];
    platform.name = @"p_grass";
    platform.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:platform.size];
    platform.position = CGPointMake(self.size.width/2.0, self.size.height/2.0);
    [self addChild:platform];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
What we did was to add one liner scene PhysicsWorld initialization specifying the gravity to a vector. What is vector? If you paid attention in your algebra class you'd know it :P. In simple terms, vector is simply a collection of values that defines direction and magnitude. In our case, SpriteKit is a 2 dimensional space. So it has x and y vector components in a normal Cartesian axes. So to specify a downward gravity, use (0, negative value). Here we use (0,-5) for a fairly moderate pull force to the bottom. If you want the scene environment to pull everything to the top, then you use (0,9), if you want to pull everything to the left, then you use (-8, 0), and if you want to pull everything to bottom left, you can use (-8, -7).&lt;br /&gt;
&lt;br /&gt;
After specifying the scene physics, we also need to specify which of our sprites will be affected by it. So we have to add the physicsBody definition to our spritenode.&amp;nbsp; There are multiple types of physicsBody, and here we use Rectangle type. There are types of:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;RectangleWithSize (specify CGSize)&lt;/li&gt;
&lt;li&gt;CircleWithRadius (specify float radius)&lt;/li&gt;
&lt;li&gt;PolygonFromPath (specify path of custom shape)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Most people simply use rectangle or circle for physicsbody, unless you are doing something complicated, polygon physicsbody should not be used. Anyway lets run our game, what's going on?&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXMoB53MerbcMjBd7W6idBwixeC76L_XT66dLiw-Pb219_VfLwgcmGAQVzGBCGOYE6Ld4m6d6AKi9kqnRgXc8BxFob53WQuYLrY9cwjkcDb4xd9cophKCFJbGAkCWaXI19fT-6LHfbvIU/s1600/Dec-29-2019+10-55-21.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="586" data-original-width="331" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXMoB53MerbcMjBd7W6idBwixeC76L_XT66dLiw-Pb219_VfLwgcmGAQVzGBCGOYE6Ld4m6d6AKi9kqnRgXc8BxFob53WQuYLrY9cwjkcDb4xd9cophKCFJbGAkCWaXI19fT-6LHfbvIU/s320/Dec-29-2019+10-55-21.gif" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
LOL! Both of them fall down... but duh.. that is exactly what the code says. And that means the physics is now in action. Ok lets take a break to award ourselves with this accomplishment. XD&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Obviously we do not want the platform to fall, but yet we still need it to be affected by physics in order to interact with the bunny. If we remove the physicsbody from the platform spritenode, the bunny will ignore the platform like it's not even there. Try it yourself. Here is what you should get:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHcYBG1QA9eo3fbyAI2lWXkd5aJGoZFKS5rMyEM8SIfP8GAGVScJR-88GOu0o75i-XRK8GExibxFZCEghkQatjFOyGvw2odTEXuH_ANN80I6NjMqV5zKzmSscSQkJGjcP8X4zvHErsvd0/s1600/Dec-29-2019+10-55-32.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="586" data-original-width="331" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHcYBG1QA9eo3fbyAI2lWXkd5aJGoZFKS5rMyEM8SIfP8GAGVScJR-88GOu0o75i-XRK8GExibxFZCEghkQatjFOyGvw2odTEXuH_ANN80I6NjMqV5zKzmSscSQkJGjcP8X4zvHErsvd0/s320/Dec-29-2019+10-55-32.gif" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So to tell the platform not to be affected by gravity, but yet be able to interact with the bunny, we specify a boolean to a property&amp;nbsp;&lt;span style="background-color: #1d1f21; color: #c5c8c6; font-family: monospace; font-size: 12.1px; white-space: pre;"&gt;affectedByGravity&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
platform.physicsBody.affectedByGravity = NO;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Add the line under the physicsBody definition of the platform spritenode and you should end up with the following:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjn8_Ejoms85mKB-CuBlhNh1tAz05ztKeYOks0kKydW7t5zocml6LJn_FlvtntdXsCWpq6UZJFPrv-l-KGUUy-T3ufQexBB03rdMi-nSQfSsQiawqgA36N1I09ccIZahae1VVtJHYWL38/s1600/Dec-29-2019+11-01-10.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="586" data-original-width="331" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjn8_Ejoms85mKB-CuBlhNh1tAz05ztKeYOks0kKydW7t5zocml6LJn_FlvtntdXsCWpq6UZJFPrv-l-KGUUy-T3ufQexBB03rdMi-nSQfSsQiawqgA36N1I09ccIZahae1VVtJHYWL38/s320/Dec-29-2019+11-01-10.gif" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
Woah? We still FAIL. But there are progress. As we can see, the bunny now interacts with the platform. The platform no longer falls down by itself but it is being forced down by the weight of the bunny. How do we solve this? Enter the dynamic property of physicsBody.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;platform.physicsBody.dynamic = NO;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
This tells the physics engine that the platform will ignore any force applied to it. And you will end up with:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimoFre5mXwiLixifc_Tmkz6DK8EbZ2HyC6LiP7LWJy8-CwaVTHNO1AoDdA6sTYSCSIiCyXD0ezU1PJEcE-CXKCVJexwlDPAl0IishShNLpLwfDIHaX8WgjVzwB6MX_8afhd677vWoTbZk/s1600/Dec-29-2019+11-04-36.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="586" data-original-width="331" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimoFre5mXwiLixifc_Tmkz6DK8EbZ2HyC6LiP7LWJy8-CwaVTHNO1AoDdA6sTYSCSIiCyXD0ezU1PJEcE-CXKCVJexwlDPAl0IishShNLpLwfDIHaX8WgjVzwB6MX_8afhd677vWoTbZk/s320/Dec-29-2019+11-04-36.gif" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq" style="clear: both; text-align: left;"&gt;
As you can see, now the bunny bounces a bit as he lands. This is physics at work. We did not write ANY codes for this bounces. Movements looks more natural and nice and human can relate to it and this is an important factor to capture human's interest in your game.&lt;/blockquote&gt;
&lt;br /&gt;
The final code is:
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
    self.physicsWorld.gravity = CGVectorMake(0, -3.0f);
    
    //create bunny
    SKSpriteNode *bunny = [SKSpriteNode spriteNodeWithImageNamed:@"bunny"];
    bunny.name = @"bunny";
    bunny.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bunny.size];
    bunny.position = CGPointMake(self.size.width/2.0, self.size.height/2.0+200);
    [self addChild:bunny];

    SKSpriteNode *platform = [SKSpriteNode spriteNodeWithImageNamed:@"p_grass"];
    platform.name = @"p_grass";
    platform.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:platform.size];
    platform.physicsBody.affectedByGravity = NO;
    platform.physicsBody.dynamic = NO;
    platform.position = CGPointMake(self.size.width/2.0, self.size.height/2.0);
    [self addChild:platform];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
As you can see, I reduced the gravity a bit because I wanted to be able to capture the animation and show you what's going on. I also moved the bunny further up by 200 points. As you can see, now the bunny bounces a bit as he lands. This is physics at work. We did not write ANY codes for this bounces. Movements looks more natural and nice and human can relate to it and this is an important factor to capture human's interest in your game.&lt;br /&gt;
&lt;br /&gt;
Now we got the bunny to land and bounce on the platform, we are that much closer to a platform game like Mario. The next thing to do is add more platforms and code the controls for the bunny. How do we make him jump? Enter the code below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    SKSpriteNode *bunny = (SKSpriteNode*)[self childNodeWithName:@"bunny"];
    [bunny.physicsBody applyImpulse:CGVectorMake(0, 50)];
}&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
touchesBegan is a typical delegate function to detect finger touches on screen. We use this to tell our bunny to jump. In order to jump, an upward momentary force (impulse) is applied once every time we touch the screen. And the results:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihlzye6njYzOAwEg-0PaMKaNItADCq0Fsp7Cs9XT9r3vQIc5R9CQVhB8fxGialNyl_WyStTLxLX7gD0Y4r6tNRBV4XfM1omffkAaz76iLrxvquEtBA-FsW1mHSha9yNBKJ1BWlwk9quHI/s1600/Dec-31-2019+19-11-06.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="360" data-original-width="334" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihlzye6njYzOAwEg-0PaMKaNItADCq0Fsp7Cs9XT9r3vQIc5R9CQVhB8fxGialNyl_WyStTLxLX7gD0Y4r6tNRBV4XfM1omffkAaz76iLrxvquEtBA-FsW1mHSha9yNBKJ1BWlwk9quHI/s320/Dec-31-2019+19-11-06.gif" width="296" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Success! Now we have a bunny jumping on a platform. There is another way to make the bunny jump, such as setting velocity of bunny to positive value on the Y axis. And you can fine tune the gravity, the jump speed, bounciness, all by tweaking the gravity, the impulse value, and also a few more bunny's physicBody's properties:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;restitution&lt;/li&gt;
&lt;li&gt;mass&lt;/li&gt;
&lt;li&gt;friction&lt;/li&gt;
&lt;li&gt;density&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Experiment with the values and see what you could come up with. That's all for Part 1 of this tutorial. I will delve in more in the next part so that at least we got a playable simple game collecting coins or carrots :P&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Cheers and have a nice day!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://www.dropbox.com/s/hgmrgj2zo3tgxdb/BunnyPart1.zip?dl=0" style="margin-left: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJxG0OiR4I5cgBN5SVtYoQvK4JjHyT-EsRjiDs6Mu8MH_mPgcSoDbpQmPK6jn8bpdTw9vdrj_QZ24_lqOwr8DvRqS-s7KRYw1egiWp1QcukVoy7tu3bEdU1myqnW_nrXXm7gdhunCWdy8/s320/download.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
</description><link>http://xcodenoobies.blogspot.com/2019/12/tutorial-part-i-basic-of-spritekits.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhayurdvRe4VQsDD9AFcRKF2uonIjWNBmyeQFiieExdLndmtZRRSZFmPN22qWx0uQweriVyUrEDFVRnQYMq6OlhmtFq89L3wc81_IijCAPgDpSwFY8PdIU_0cSl_to0w9IIz0H1mTEC6Wo/s72-c/tandy-8499.jpg" width="72"/><thr:total>0</thr:total><enclosure length="-1" type="application/json" url="https://www.dropbox.com/s/hgmrgj2zo3tgxdb/BunnyPart1.zip?dl=0"/><itunes:explicit/><itunes:subtitle>Another year is gone. I remember when I was a little boy, I'd be hyped when people talk about the "FUTURE". That time, circa 1980s, the "FUTURE" means anywhere in the year 2000+. The year 2020 is somewhat special though due to its nice number arrangement. 2020 itself sounds futuristic. But lo and behold, we are almost there now! 40 years have passed just like that. I have to admit when you reach 40, time seems to go by much more faster. It seems you have so much to do, but there isn't just enough time to do it. Get busy living, get busy dying. 20MHz Processor LMAO. 8 Grand&amp;nbsp; In terms of tech, no doubt we have progressed so much. Imagine back then in 1980 a computer with very low specs are so expensive. In terms of computing power, and computing tools like Machine Learning, AI, OCR, and so on we have made quite the leap. Imagine what engineers and scientists could achieve in another 40 years? Most probably I'd be dead by then :P Done with the intro. So, the first ever game I created from scratch with SpriteKit was the Flappy Bird clone called "Idiot Bird". It was quite a challenge, because I was new to SpriteKit, and Idiot Bird uses physics in order for the bird to fly. And who could forget the way the bird smash its face flat to the ground? Haha... Believe it or not, my first game I developed in iOS was using 100% UIKit using UIImageView as sprites. Here take a look: I used Paint Shop Pro to create all the (nasty nasty raster) graphics and place them using UIImageViews. It worked quite OK, because it was a turned based game. And animation is smooth just by using a normal UIView animation. This is a monumental evidence that UIKit is such a great framework. Windows framework fails miserably if you try to animate their buttons. There is no fluidity. Anyway, lets get to topic: SpriteKit's Physics. You can create a Spritekit game without any physics setup. But the kind of games you can make is therefore limited. Games that won't use physics are like Chess game, or card game, or even simple shooting game (top view typically). But if you wish to make a game that feels real, Physics is a must. For this purpose, we will create a simple scene. A character bouncing on a platform. The first thing to do is to add 2 sprites to a scene. With my amazing graphics skills (lol), here is what I created: You may download the image and resize it for other scales. Add both sprites to the scene in didMoveToView and position the character slightly above the platform. - (void)didMoveToView:(SKView *)view { //create bunny SKSpriteNode *bunny = [SKSpriteNode spriteNodeWithImageNamed:@"bunny"]; bunny.name = @"bunny"; bunny.position = CGPointMake(self.size.width/2.0, self.size.height/2.0+100); [self addChild:bunny]; //create platform SKSpriteNode *platform = [SKSpriteNode spriteNodeWithImageNamed:@"p_grass"]; platform.name = @"p_grass"; platform.position = CGPointMake(self.size.width/2.0, self.size.height/2.0); [self addChild:platform]; } Run it, and you will see both of them in the scene. But... nothing happens. Boring right? So how do we tell the scene that we want to apply gravity to the sprites in the scene so that the bunny would fall? Easy. Enter the codes below: // scene physics initialization self.physicsWorld.gravity = CGVectorMake(0, -5.0f); //create bunny SKSpriteNode *bunny = [SKSpriteNode spriteNodeWithImageNamed:@"bunny"]; bunny.name = @"bunny"; bunny.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bunny.size]; bunny.position = CGPointMake(self.size.width/2.0, self.size.height/2.0+100); [self addChild:bunny]; SKSpriteNode *platform = [SKSpriteNode spriteNodeWithImageNamed:@"p_grass"]; platform.name = @"p_grass"; platform.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:platform.size]; platform.position = CGPointMake(self.size.width/2.0, self.size.height/2.0); [self addChild:platform]; What we did was to add one liner scene PhysicsWorld initialization specifying the gravity to a vector. What is vector? If you paid attention in your algebra class you'd know it :P. In simple terms, vector is simply a collection of values that defines direction and magnitude. In our case, SpriteKit is a 2 dimensional space. So it has x and y vector components in a normal Cartesian axes. So to specify a downward gravity, use (0, negative value). Here we use (0,-5) for a fairly moderate pull force to the bottom. If you want the scene environment to pull everything to the top, then you use (0,9), if you want to pull everything to the left, then you use (-8, 0), and if you want to pull everything to bottom left, you can use (-8, -7). After specifying the scene physics, we also need to specify which of our sprites will be affected by it. So we have to add the physicsBody definition to our spritenode.&amp;nbsp; There are multiple types of physicsBody, and here we use Rectangle type. There are types of: RectangleWithSize (specify CGSize) CircleWithRadius (specify float radius) PolygonFromPath (specify path of custom shape) Most people simply use rectangle or circle for physicsbody, unless you are doing something complicated, polygon physicsbody should not be used. Anyway lets run our game, what's going on? LOL! Both of them fall down... but duh.. that is exactly what the code says. And that means the physics is now in action. Ok lets take a break to award ourselves with this accomplishment. XD Obviously we do not want the platform to fall, but yet we still need it to be affected by physics in order to interact with the bunny. If we remove the physicsbody from the platform spritenode, the bunny will ignore the platform like it's not even there. Try it yourself. Here is what you should get: So to tell the platform not to be affected by gravity, but yet be able to interact with the bunny, we specify a boolean to a property&amp;nbsp;affectedByGravity platform.physicsBody.affectedByGravity = NO; Add the line under the physicsBody definition of the platform spritenode and you should end up with the following: Woah? We still FAIL. But there are progress. As we can see, the bunny now interacts with the platform. The platform no longer falls down by itself but it is being forced down by the weight of the bunny. How do we solve this? Enter the dynamic property of physicsBody. platform.physicsBody.dynamic = NO; This tells the physics engine that the platform will ignore any force applied to it. And you will end up with: As you can see, now the bunny bounces a bit as he lands. This is physics at work. We did not write ANY codes for this bounces. Movements looks more natural and nice and human can relate to it and this is an important factor to capture human's interest in your game. The final code is: self.physicsWorld.gravity = CGVectorMake(0, -3.0f); //create bunny SKSpriteNode *bunny = [SKSpriteNode spriteNodeWithImageNamed:@"bunny"]; bunny.name = @"bunny"; bunny.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bunny.size]; bunny.position = CGPointMake(self.size.width/2.0, self.size.height/2.0+200); [self addChild:bunny]; SKSpriteNode *platform = [SKSpriteNode spriteNodeWithImageNamed:@"p_grass"]; platform.name = @"p_grass"; platform.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:platform.size]; platform.physicsBody.affectedByGravity = NO; platform.physicsBody.dynamic = NO; platform.position = CGPointMake(self.size.width/2.0, self.size.height/2.0); [self addChild:platform]; As you can see, I reduced the gravity a bit because I wanted to be able to capture the animation and show you what's going on. I also moved the bunny further up by 200 points. As you can see, now the bunny bounces a bit as he lands. This is physics at work. We did not write ANY codes for this bounces. Movements looks more natural and nice and human can relate to it and this is an important factor to capture human's interest in your game. Now we got the bunny to land and bounce on the platform, we are that much closer to a platform game like Mario. The next thing to do is add more platforms and code the controls for the bunny. How do we make him jump? Enter the code below: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { SKSpriteNode *bunny = (SKSpriteNode*)[self childNodeWithName:@"bunny"]; [bunny.physicsBody applyImpulse:CGVectorMake(0, 50)]; } touchesBegan is a typical delegate function to detect finger touches on screen. We use this to tell our bunny to jump. In order to jump, an upward momentary force (impulse) is applied once every time we touch the screen. And the results: Success! Now we have a bunny jumping on a platform. There is another way to make the bunny jump, such as setting velocity of bunny to positive value on the Y axis. And you can fine tune the gravity, the jump speed, bounciness, all by tweaking the gravity, the impulse value, and also a few more bunny's physicBody's properties: restitution mass friction density Experiment with the values and see what you could come up with. That's all for Part 1 of this tutorial. I will delve in more in the next part so that at least we got a playable simple game collecting coins or carrots :P Cheers and have a nice day!</itunes:subtitle><itunes:author>noreply@blogger.com (GeneCode)</itunes:author><itunes:summary>Another year is gone. I remember when I was a little boy, I'd be hyped when people talk about the "FUTURE". That time, circa 1980s, the "FUTURE" means anywhere in the year 2000+. The year 2020 is somewhat special though due to its nice number arrangement. 2020 itself sounds futuristic. But lo and behold, we are almost there now! 40 years have passed just like that. I have to admit when you reach 40, time seems to go by much more faster. It seems you have so much to do, but there isn't just enough time to do it. Get busy living, get busy dying. 20MHz Processor LMAO. 8 Grand&amp;nbsp; In terms of tech, no doubt we have progressed so much. Imagine back then in 1980 a computer with very low specs are so expensive. In terms of computing power, and computing tools like Machine Learning, AI, OCR, and so on we have made quite the leap. Imagine what engineers and scientists could achieve in another 40 years? Most probably I'd be dead by then :P Done with the intro. So, the first ever game I created from scratch with SpriteKit was the Flappy Bird clone called "Idiot Bird". It was quite a challenge, because I was new to SpriteKit, and Idiot Bird uses physics in order for the bird to fly. And who could forget the way the bird smash its face flat to the ground? Haha... Believe it or not, my first game I developed in iOS was using 100% UIKit using UIImageView as sprites. Here take a look: I used Paint Shop Pro to create all the (nasty nasty raster) graphics and place them using UIImageViews. It worked quite OK, because it was a turned based game. And animation is smooth just by using a normal UIView animation. This is a monumental evidence that UIKit is such a great framework. Windows framework fails miserably if you try to animate their buttons. There is no fluidity. Anyway, lets get to topic: SpriteKit's Physics. You can create a Spritekit game without any physics setup. But the kind of games you can make is therefore limited. Games that won't use physics are like Chess game, or card game, or even simple shooting game (top view typically). But if you wish to make a game that feels real, Physics is a must. For this purpose, we will create a simple scene. A character bouncing on a platform. The first thing to do is to add 2 sprites to a scene. With my amazing graphics skills (lol), here is what I created: You may download the image and resize it for other scales. Add both sprites to the scene in didMoveToView and position the character slightly above the platform. - (void)didMoveToView:(SKView *)view { //create bunny SKSpriteNode *bunny = [SKSpriteNode spriteNodeWithImageNamed:@"bunny"]; bunny.name = @"bunny"; bunny.position = CGPointMake(self.size.width/2.0, self.size.height/2.0+100); [self addChild:bunny]; //create platform SKSpriteNode *platform = [SKSpriteNode spriteNodeWithImageNamed:@"p_grass"]; platform.name = @"p_grass"; platform.position = CGPointMake(self.size.width/2.0, self.size.height/2.0); [self addChild:platform]; } Run it, and you will see both of them in the scene. But... nothing happens. Boring right? So how do we tell the scene that we want to apply gravity to the sprites in the scene so that the bunny would fall? Easy. Enter the codes below: // scene physics initialization self.physicsWorld.gravity = CGVectorMake(0, -5.0f); //create bunny SKSpriteNode *bunny = [SKSpriteNode spriteNodeWithImageNamed:@"bunny"]; bunny.name = @"bunny"; bunny.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bunny.size]; bunny.position = CGPointMake(self.size.width/2.0, self.size.height/2.0+100); [self addChild:bunny]; SKSpriteNode *platform = [SKSpriteNode spriteNodeWithImageNamed:@"p_grass"]; platform.name = @"p_grass"; platform.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:platform.size]; platform.position = CGPointMake(self.size.width/2.0, self.size.height/2.0); [self addChild:platform]; What we did was to add one liner scene PhysicsWorld initialization specifying the gravity to a vector. What is vector? If you paid attention in your algebra class you'd know it :P. In simple terms, vector is simply a collection of values that defines direction and magnitude. In our case, SpriteKit is a 2 dimensional space. So it has x and y vector components in a normal Cartesian axes. So to specify a downward gravity, use (0, negative value). Here we use (0,-5) for a fairly moderate pull force to the bottom. If you want the scene environment to pull everything to the top, then you use (0,9), if you want to pull everything to the left, then you use (-8, 0), and if you want to pull everything to bottom left, you can use (-8, -7). After specifying the scene physics, we also need to specify which of our sprites will be affected by it. So we have to add the physicsBody definition to our spritenode.&amp;nbsp; There are multiple types of physicsBody, and here we use Rectangle type. There are types of: RectangleWithSize (specify CGSize) CircleWithRadius (specify float radius) PolygonFromPath (specify path of custom shape) Most people simply use rectangle or circle for physicsbody, unless you are doing something complicated, polygon physicsbody should not be used. Anyway lets run our game, what's going on? LOL! Both of them fall down... but duh.. that is exactly what the code says. And that means the physics is now in action. Ok lets take a break to award ourselves with this accomplishment. XD Obviously we do not want the platform to fall, but yet we still need it to be affected by physics in order to interact with the bunny. If we remove the physicsbody from the platform spritenode, the bunny will ignore the platform like it's not even there. Try it yourself. Here is what you should get: So to tell the platform not to be affected by gravity, but yet be able to interact with the bunny, we specify a boolean to a property&amp;nbsp;affectedByGravity platform.physicsBody.affectedByGravity = NO; Add the line under the physicsBody definition of the platform spritenode and you should end up with the following: Woah? We still FAIL. But there are progress. As we can see, the bunny now interacts with the platform. The platform no longer falls down by itself but it is being forced down by the weight of the bunny. How do we solve this? Enter the dynamic property of physicsBody. platform.physicsBody.dynamic = NO; This tells the physics engine that the platform will ignore any force applied to it. And you will end up with: As you can see, now the bunny bounces a bit as he lands. This is physics at work. We did not write ANY codes for this bounces. Movements looks more natural and nice and human can relate to it and this is an important factor to capture human's interest in your game. The final code is: self.physicsWorld.gravity = CGVectorMake(0, -3.0f); //create bunny SKSpriteNode *bunny = [SKSpriteNode spriteNodeWithImageNamed:@"bunny"]; bunny.name = @"bunny"; bunny.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bunny.size]; bunny.position = CGPointMake(self.size.width/2.0, self.size.height/2.0+200); [self addChild:bunny]; SKSpriteNode *platform = [SKSpriteNode spriteNodeWithImageNamed:@"p_grass"]; platform.name = @"p_grass"; platform.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:platform.size]; platform.physicsBody.affectedByGravity = NO; platform.physicsBody.dynamic = NO; platform.position = CGPointMake(self.size.width/2.0, self.size.height/2.0); [self addChild:platform]; As you can see, I reduced the gravity a bit because I wanted to be able to capture the animation and show you what's going on. I also moved the bunny further up by 200 points. As you can see, now the bunny bounces a bit as he lands. This is physics at work. We did not write ANY codes for this bounces. Movements looks more natural and nice and human can relate to it and this is an important factor to capture human's interest in your game. Now we got the bunny to land and bounce on the platform, we are that much closer to a platform game like Mario. The next thing to do is add more platforms and code the controls for the bunny. How do we make him jump? Enter the code below: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { SKSpriteNode *bunny = (SKSpriteNode*)[self childNodeWithName:@"bunny"]; [bunny.physicsBody applyImpulse:CGVectorMake(0, 50)]; } touchesBegan is a typical delegate function to detect finger touches on screen. We use this to tell our bunny to jump. In order to jump, an upward momentary force (impulse) is applied once every time we touch the screen. And the results: Success! Now we have a bunny jumping on a platform. There is another way to make the bunny jump, such as setting velocity of bunny to positive value on the Y axis. And you can fine tune the gravity, the jump speed, bounciness, all by tweaking the gravity, the impulse value, and also a few more bunny's physicBody's properties: restitution mass friction density Experiment with the values and see what you could come up with. That's all for Part 1 of this tutorial. I will delve in more in the next part so that at least we got a playable simple game collecting coins or carrots :P Cheers and have a nice day!</itunes:summary><itunes:keywords>basic, beginner, easy, game, mario, objective c, platform, Spritekit, tutorial</itunes:keywords></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-5084692367851259477</guid><pubDate>Sat, 31 Aug 2019 03:48:00 +0000</pubDate><atom:updated>2019-08-30T21:06:17.554-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cocoapods</category><category domain="http://www.blogger.com/atom/ns#">installation</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">newbie</category><category domain="http://www.blogger.com/atom/ns#">obj c</category><category domain="http://www.blogger.com/atom/ns#">objective c</category><category domain="http://www.blogger.com/atom/ns#">swift</category><category domain="http://www.blogger.com/atom/ns#">tutorial</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><title>How To: Use Cocoapods for Your XCode Projects</title><description>Hi guys. Been a while eh? As for me, been busy with updating my apps. I just updated one of my kids game Eggs Surprise With Friends. Improved on the graphics and gameplay based on user feedback back in 2016 HAHAH! First, an intro.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Dnn1-GgsMcVmRYM4rqh-U-xG4seioYjSnvskCOAS85VK5rue837xIhrYxwycyEkaH-FeBbPYKhdsHfCgTSxX74stMMax_bpe0X8xPDDgYz_1jPxodSuerVWVmsU74GS28dlY-H6hMsU/s1600/yuval-noah-harari-quote-10.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="572" data-original-width="1007" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Dnn1-GgsMcVmRYM4rqh-U-xG4seioYjSnvskCOAS85VK5rue837xIhrYxwycyEkaH-FeBbPYKhdsHfCgTSxX74stMMax_bpe0X8xPDDgYz_1jPxodSuerVWVmsU74GS28dlY-H6hMsU/s320/yuval-noah-harari-quote-10.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Human beings rely on blind beliefs to have a large-scale cooperation. We all believe in something that is not there physically. We believe in God (some of us not all of course). God is nowhere to be seen, cannot be measured, cannot be heard, cannot be touched. We believe in our country. Yet, a country is merely a make belief concept, and exists only in maps. We believe in the company we work in. But the company does not exist other than on papers. Our collective belief that the company exists, make us feel we belong to it, and therefore we can together work towards a common goal - be it increasing the company's profits for employees' benefits, or prospering a nation, or mass producing products. Belief in the unseen is important and needed for humanity, unless when it starts to oppress others.&lt;br /&gt;
&lt;br /&gt;
How's that for an intro? :D&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
Back to topic: COCOAPODS.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2V7LJ8pOa9WfzAKGOgYmYLlKWuHsxSJ5SGjrPEfOVapvZKSObvvuRIRsGkRRtWoxjb8GDYM5p5Zq9GvSL3sLBkEGBnj66g4gueiNf1XCPPF1sRkwSGDY7GbqHH7egQISeQpvCDLHhk9o/s1600/wall-murals-cocoa-pod.jpg.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="493" data-original-width="700" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2V7LJ8pOa9WfzAKGOgYmYLlKWuHsxSJ5SGjrPEfOVapvZKSObvvuRIRsGkRRtWoxjb8GDYM5p5Zq9GvSL3sLBkEGBnj66g4gueiNf1XCPPF1sRkwSGDY7GbqHH7egQISeQpvCDLHhk9o/s320/wall-murals-cocoa-pod.jpg.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Wow I never saw an actual cocoa pod before.. now I know how it looks like! What a great thing google is. What is CocoaPods? Why is it called Cocoa? Cocoa is basically Programming API for Mac OSX. Basically it is a set of functions, classes, frameworks that enables you to create a Mac Applications/Softwares. And iOS imports some of those as well. Back then, I was so occupied in creating my own controls, customizing UI is one of the fun thing to do! I still love to customize UIs. Here are some of the controls that I made in the past - ranging from noobiest, to a fairly intermediate level where I am now.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Slide To Unlock, replicating the iconic iOS's Slide to Unlock button.&amp;nbsp;&lt;a href="https://xcodenoobies.blogspot.com/2011/03/how-to-do-slide-to-unlock.html"&gt;https://xcodenoobies.blogspot.com/2011/03/how-to-do-slide-to-unlock.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;UISwitchy, a flexible customizable Switch.&amp;nbsp;&lt;a href="https://xcodenoobies.blogspot.com/2013/04/free-custom-uiswitch-flexible-colors.html"&gt;https://xcodenoobies.blogspot.com/2013/04/free-custom-uiswitch-flexible-colors.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GCToolBar, a flexible classy looking Toolbar.&amp;nbsp;&lt;a href="https://github.com/gene-code/GCToolBar"&gt;https://github.com/gene-code/GCToolBar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GCSpriteAlert, an Alert Box that looks like the UIKit one, but on SpriteKit.&amp;nbsp;&lt;a href="https://github.com/gene-code/GCSpriteAlert"&gt;https://github.com/gene-code/GCSpriteAlert&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
CocoaPods are basically small components that are made by other developers worldwide, using Cocoa. When I learnt about cocoapods, I couldn't really understand what it is. A simple way to explain is CocoaPods is like more options to your UIViews, UISwitch, and UITableViews. You can contribute to it by making your own controls and user interface objects. Or you can simply use them.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
For example, lets say you are making a drawing app. You need to code the drawing part, how the touches translates to lines and curves. And then you also need a way to pick a pen color. Here is where you have that option - do you create your own color picker?? Or, simply import a color picker object made by others from CocoaPods library? There are plenty of CocoaPods color pickers. You can browse them here: &lt;a href="https://cocoapods.org/"&gt;https://cocoapods.org&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg92qHeZ582mhyRXfZ5Juws993_OvRtEwBzabDH9vvn1XLPE5P0-bEAUb0fHPT6lEvBqAgExc97JYwgcrcDuMQfFH69Zl13ZPsN6NHvRayOsAYSaDJKM7cw92fqWYeiYUShNs3S3ezyqaI/s1600/colorpicker.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="585" data-original-width="804" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg92qHeZ582mhyRXfZ5Juws993_OvRtEwBzabDH9vvn1XLPE5P0-bEAUb0fHPT6lEvBqAgExc97JYwgcrcDuMQfFH69Zl13ZPsN6NHvRayOsAYSaDJKM7cw92fqWYeiYUShNs3S3ezyqaI/s320/colorpicker.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
But how do we add any of these cocoapods to our XCode project? Here is where I got lost and gave up on CocoaPods lol. No don't give up. I will teach you how.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
First step is to INSTALL COCOAPODS into your Mac. This is easy really. You are going to use some terminal commands but don't worry it is really straight forward. I actually outlined it in the StackOverflow answer &lt;a href="https://stackoverflow.com/a/25257238/501439"&gt;here&lt;/a&gt;, but I am going to outline it again here in this blogpost in case somebody edited that answer.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;b&gt;[ 1 ] &lt;/b&gt;Open terminal and type:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class="lang-swift prettyprint prettyprinted" style="background-color: #eff0f1; border-radius: 3px; border: 0px; box-sizing: inherit; color: #393318; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; max-height: 600px; overflow-wrap: normal; overflow: auto; padding: 12px 8px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline; white-space: inherit;"&gt;&lt;span class="pln" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;sudo gem install cocoapods&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
Gem will get installed in Ruby inside System library. Or try on 10.11 Mac OSX El Capitan, type:&lt;/div&gt;
&lt;pre class="lang-swift prettyprint prettyprinted" style="background-color: #eff0f1; border-radius: 3px; border: 0px; box-sizing: inherit; color: #393318; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; max-height: 600px; overflow-wrap: normal; overflow: auto; padding: 12px 8px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline; white-space: inherit;"&gt;&lt;span class="pln" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;sudo gem install &lt;/span&gt;&lt;span class="pun" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;-&lt;/span&gt;&lt;span class="pln" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;n &lt;/span&gt;&lt;span class="pun" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;/&lt;/span&gt;&lt;span class="pln" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;usr&lt;/span&gt;&lt;span class="pun" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;/&lt;/span&gt;&lt;span class="pln" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;local&lt;/span&gt;&lt;span class="pun" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;/&lt;/span&gt;&lt;span class="pln" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;bin cocoapods&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
If there is an error "activesupport requires Ruby version &amp;gt;= 2.xx", then install latest activesupport first by typing in terminal.&lt;/div&gt;
&lt;pre class="lang-swift prettyprint prettyprinted" style="background-color: #eff0f1; border-radius: 3px; border: 0px; box-sizing: inherit; color: #393318; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; max-height: 600px; overflow-wrap: normal; overflow: auto; padding: 12px 8px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline; white-space: inherit;"&gt;&lt;span class="pln" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;sudo gem install activesupport &lt;/span&gt;&lt;span class="pun" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;-&lt;/span&gt;&lt;span class="pln" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;v &lt;/span&gt;&lt;span class="lit" style="border: 0px; box-sizing: inherit; color: #7d2727; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;4&lt;/span&gt;&lt;span class="pun" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;.&lt;/span&gt;&lt;span class="lit" style="border: 0px; box-sizing: inherit; color: #7d2727; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;2&lt;/span&gt;&lt;span class="pun" style="border: 0px; box-sizing: inherit; color: #303336; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;.&lt;/span&gt;&lt;span class="lit" style="border: 0px; box-sizing: inherit; color: #7d2727; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;6&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;b&gt;[ 2 ]&lt;/b&gt; After installation, there will be a lot of messages, read them and if no error found, it means cocoapods installation is done. Next, you need to setup the cocoapods master repo&lt;b&gt;.&lt;/b&gt; Type in terminal:&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;pod setup&lt;/code&gt;&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
And wait it will download the master repo. The size is very big (370.0MB at Dec 2016). So it can be a while. You can track of the download by opening Activity and goto Network tab and search for git-remote-https. Alternatively you can try adding verbose to the command like so:&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;pod setup --verbose&lt;/code&gt;&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;b&gt;[ 3 ]&lt;/b&gt; Once done it will output "Setup Complete", and you can create your XCode project and save it.&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;b&gt;[ 4 ]&lt;/b&gt; Then in terminal cd to "your XCode project root directory" (where your&amp;nbsp;&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;.xcodeproj&lt;/code&gt;&amp;nbsp;file resides) and type:&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;pod init&lt;/code&gt;&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;b&gt;[ 5 ] &lt;/b&gt;Then open your project's podfile by typing in terminal (or open using Atom/TextEdit/Notepad++ etc):&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;open -a Xcode Podfile&lt;/code&gt;&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;b&gt;[ 6 ] &lt;/b&gt;Your Podfile will get open in text mode. Initially there will be some default commands in there. Here is where you add your project's dependencies. For example, in the podfile, type&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;pod 'AFNetworking', '0.9.1'&lt;/code&gt;&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
(this line is an example of adding the AFNetworking library to your project).&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
Other tips:&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
Uncomment&amp;nbsp;&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;platform :ios, '9.0'&lt;/code&gt;&amp;nbsp;Uncomment&amp;nbsp;&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;user_frameworks!&lt;/code&gt;&amp;nbsp;if you're using Swift&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
When you are done editing the podfile, save it and close Xcode.&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;b&gt;[ 7 ] &lt;/b&gt;Then install pods into your project by typing in terminal:&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;pod install&lt;/code&gt;&lt;/div&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
Depending how many libraries you added to your podfile for your project, the time to complete this varies. Once completed, there will be a message that says&lt;/div&gt;
&lt;blockquote style="background-color: cornsilk; border-bottom-color: initial; border-bottom-style: initial; border-image: initial; border-left-color: rgb(255, 235, 142); border-left-style: solid; border-right-color: initial; border-right-style: initial; border-top-color: initial; border-top-style: initial; border-width: 0px 0px 0px 2px; box-sizing: inherit; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin: 0px 0px 10px; padding: 10px; quotes: none; vertical-align: baseline;"&gt;
&lt;div style="border: 0px; box-sizing: inherit; clear: both; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; padding: 0px; vertical-align: baseline;"&gt;
"Pod installation complete! There are X dependencies from the Podfile and X total pods installed."&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style="background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #242729; font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1em; padding: 0px; vertical-align: baseline;"&gt;
Now close your Xcode project. Then&amp;nbsp;&lt;em style="border: 0px; box-sizing: inherit; font-family: inherit; font-stretch: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;locate&lt;/em&gt;&amp;nbsp;and open the&amp;nbsp;&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;.xcworkspace&lt;/code&gt;&amp;nbsp;Xcode project file and start coding. (You should no longer open the&amp;nbsp;&lt;code style="background-color: #eff0f1; border: 0px; box-sizing: inherit; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; font-size: 13px; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 1px 5px; vertical-align: baseline; white-space: pre-wrap;"&gt;xcodeproj&lt;/code&gt;&amp;nbsp;file)&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Step [6] &lt;/b&gt;is where you import any of the CocoaPods that you like to use. The command line to import is generally "pod [podname], [version]". Lets choose a cocoapod and install it. I found a iOS-color-wheel pod, so I click on it and its own page opens up. Then on the left there is a Installation Guide button, click on that and there will be a popup with the command line in the middle (see arrow).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhys2Iz1lLsDhozditMGiGwbAQYluYuzXFNsQ7nbM7IvX9vFas6JxI5HEeTArt3pFxUFoObyZQh4pdSGSET6S7TyfQ7c3YHhhWRhex_7rpXarJuuCilmcEVMUQFYv29pVwjdlNz4BLD2EU/s1600/cocoa.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="791" data-original-width="1305" height="385" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhys2Iz1lLsDhozditMGiGwbAQYluYuzXFNsQ7nbM7IvX9vFas6JxI5HEeTArt3pFxUFoObyZQh4pdSGSET6S7TyfQ7c3YHhhWRhex_7rpXarJuuCilmcEVMUQFYv29pVwjdlNz4BLD2EU/s640/cocoa.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Copy this and paste in your "Podfile" file on your text editor.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpH44yoIXoxN-5sFCZsARVtzLMHn-UD-xIELeTOCXgaM69n9gqE33nId-OGfIG-OTZeHBYREYbqfnIQLD90GpcpgQ2VrOGFQ5XQxRMhM-4DFvGixhfyKjMMPK-QwASIxZFPEExLvWpZWU/s1600/pod.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="288" data-original-width="380" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpH44yoIXoxN-5sFCZsARVtzLMHn-UD-xIELeTOCXgaM69n9gqE33nId-OGfIG-OTZeHBYREYbqfnIQLD90GpcpgQ2VrOGFQ5XQxRMhM-4DFvGixhfyKjMMPK-QwASIxZFPEExLvWpZWU/s320/pod.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;blockquote class="tr_bq"&gt;
WARNING! Do take note what language that the pod was written on. Some are Swifts some are ObjCs. So far I used ObjC only so I am not sure what happens if you use Swift's pod in an ObjC project. My guess is it won't work as expected.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
After you added the command in your Podfile, save it and return to the command line where your Podfile resides and do step [7] above.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
If later in your development, you want to add more pods to your project, then you simple open your Podfile again, copy paste the pod command lines and run the "&lt;b&gt;pod install&lt;/b&gt;" in your terminal. And then you can use those pods normally by importing their headers, like any other normal libraries/frameworks.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here is a sample of one of my apps' Podfile that uses multiple pods:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicJTNo0hz-V2jJJk45aNia7jKdvBDSJq9AgjJlP25g-FhwXCLiO5Zogc7xLIvvdO5hgwo4OIytzSRfP72EoGB6B1MjntoBRI05kTKTbdhMM0pkf6pxZLmVNVTyoCsXZxZnmXfLp8eFp1g/s1600/pod.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="392" data-original-width="401" height="312" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicJTNo0hz-V2jJJk45aNia7jKdvBDSJq9AgjJlP25g-FhwXCLiO5Zogc7xLIvvdO5hgwo4OIytzSRfP72EoGB6B1MjntoBRI05kTKTbdhMM0pkf6pxZLmVNVTyoCsXZxZnmXfLp8eFp1g/s320/pod.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here you can see I even have 2 targets (Pro and Lite app) and I only use Admob ads pod in one of the target (Lite version has ads). So everytime you update an app, you can also update your pods' version (if any, depending on their developers). Just run "pod update".&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
One last thing, is to remember to open your XCode project, by opening the newly created .&lt;b&gt;xcworkspace&lt;/b&gt; file instead of the xcodeproj file. That will load the correct files for CocoaPods to work properly with your project.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Cocoapod has grown big. A lot of developers contributed to this library. As people say, why reinvent the wheel? Well, in some case, we do need to reinvent the wheel, if there aren't any good library out there to do a particular thing, or if you think of something better, do create it and add to the pod. I am planning to add my controls to the pod as well, but maybe later after I am able to code in Swift proficiently.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
That's all for now.... cya later&lt;/div&gt;
</description><link>http://xcodenoobies.blogspot.com/2019/08/how-to-use-cocoapods-for-your-xcode.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Dnn1-GgsMcVmRYM4rqh-U-xG4seioYjSnvskCOAS85VK5rue837xIhrYxwycyEkaH-FeBbPYKhdsHfCgTSxX74stMMax_bpe0X8xPDDgYz_1jPxodSuerVWVmsU74GS28dlY-H6hMsU/s72-c/yuval-noah-harari-quote-10.jpg" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-8292607652208488876</guid><pubDate>Wed, 27 Feb 2019 11:26:00 +0000</pubDate><atom:updated>2019-02-27T03:34:40.129-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">area</category><category domain="http://www.blogger.com/atom/ns#">iphone xs</category><category domain="http://www.blogger.com/atom/ns#">iphonex</category><category domain="http://www.blogger.com/atom/ns#">safe</category><category domain="http://www.blogger.com/atom/ns#">safearea</category><category domain="http://www.blogger.com/atom/ns#">safearealayoutguide</category><category domain="http://www.blogger.com/atom/ns#">safearelayout</category><category domain="http://www.blogger.com/atom/ns#">Spritekit</category><title>How To: Update Your old SpriteKit Game to be Compatible with iPhone X, XS, XR, XS Max</title><description>Yoooo wazaaaaapppppp...&lt;br /&gt;
&lt;br /&gt;
Ok, first, a witty intro (again?).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJmfUY4KiwCyv2drXsXP0MEEi9Y-8QU5x71rIYhWtwCO91BHmpEMtJXHO43yOkdcIEACwzwGFedx-74fnVwJfWK27EhWK5MliE5-TV4XXmAGLA9i4VXhADEny6wmaNAM8uBS7nBvqohiU/s1600/Caution.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="300" data-original-width="500" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJmfUY4KiwCyv2drXsXP0MEEi9Y-8QU5x71rIYhWtwCO91BHmpEMtJXHO43yOkdcIEACwzwGFedx-74fnVwJfWK27EhWK5MliE5-TV4XXmAGLA9i4VXhADEny6wmaNAM8uBS7nBvqohiU/s320/Caution.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
We often hear people say do not disturb a developer or programmer. But often we do not understand why. It is not the same as disturbing someone who is doing a regular office job. When a programmer is coding, he is actually building a Millenium Falcon lego model in his head. All the parts are assembled in his head in groups. Once you disturb a programmer, all the groups that are built in his head (but not yet assembled), will crumble and he will have to start over from zero.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Take my advice: If you see programmer coding, DO NOT SAY ANYTHING TO HIM. DO NOT EVEN COME NEAR.&amp;nbsp;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;/div&gt;
&lt;a name='more'&gt;&lt;/a&gt;Anyway, lets go on with the tutorial:&lt;br /&gt;
&lt;br /&gt;
I actually have 2 blog posts that are WIP. Haven't got the time to finish them yet. But, as I update my SpriteKit game, I notice something weird that is happening to the Scenes in iPhone Notch. iPhone Notch is what I call all the iPhones that have notch in them like - iPhone X, XS, XR, XS Max. Check out one of my game screen when run on iPhone Notch:&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrZJzpSS78UkEnd8rRO4MPrcLsQE3XV7xVO5ixqWcP_LiKS5v6d2CDe-AiqhgxljSkKO-AVSQnh2yGMpYvfww8D6BPvtf_s8AOl1MxcHZw4CGiQP_W6Mnn4V2TeXQftCdjrUG5G_HG0BU/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="699" data-original-width="352" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrZJzpSS78UkEnd8rRO4MPrcLsQE3XV7xVO5ixqWcP_LiKS5v6d2CDe-AiqhgxljSkKO-AVSQnh2yGMpYvfww8D6BPvtf_s8AOl1MxcHZw4CGiQP_W6Mnn4V2TeXQftCdjrUG5G_HG0BU/s400/Untitled.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Basically, the whole scene get stretched and the bottom bar and title overlapped with notch and bottom line (i think it is the control center slide up menu). I saw many people on the Stackoverflow were asking similar questions, and most resort to REPOSITIONING all the sprites. This is crazy! No way in hell I am going to do so much work! There are not just one scene!&amp;nbsp;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
As a lazy ass bum developer, I went ahead and try a few things in ViewController instead without touching any of the Scenes. Lo and behold, I found solution:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

-(void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    
    if (!layoutDone) {
        layoutDone = YES;
        
        // Configure the view.
        SKView * skView = (SKView *)self.view;
        skView.multipleTouchEnabled = NO;

        // Create and configure the scene.
        SKScene * scene = [GameScene sceneWithSize:skView.bounds.size];    // LINE 1
        scene.scaleMode = SKSceneScaleModeAspectFill;                      // LINE 2
        
        // Present the scene.
        [skView presentScene:scene];

        
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
The above is the original SpriteKit code. I added layoutDone boolean check so that the scene gets drawn once. I think this code used to be in viewDidLoad in earlier versions of XCode spritekit template. But since autolayout, it has been put into viewWillLayoutSubviews.&lt;br /&gt;
&lt;br /&gt;
Anyways, the solution, replace LINE 1 and LINE 2 with the lines below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
SKScene * scene = [GameScene sceneWithSize:skView.safeAreaLayoutGuide.layoutFrame.size]; // LINE 1
scene.scaleMode = SKSceneScaleModeAspectFit;                                             // LINE 2
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
Basically, we init the scene with the safeArea layout size, and set the scalemode to aspect&lt;b&gt;Fit&lt;/b&gt;. Just these two lines and voila:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYBYGKmDuCPYnDXjWS0N3-h4uIFmYdEX86cPD9ty52rkQpkS2vCqnH16uxVWqFk9r6RVv4D4iSH9JK1YnUc3AIbazzVrspxUSVImL-ZPGmLQ6CP6iz1GAZgb-j0oWWBdOJtpooA7BXRzU/s1600/Untitled2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="696" data-original-width="344" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYBYGKmDuCPYnDXjWS0N3-h4uIFmYdEX86cPD9ty52rkQpkS2vCqnH16uxVWqFk9r6RVv4D4iSH9JK1YnUc3AIbazzVrspxUSVImL-ZPGmLQ6CP6iz1GAZgb-j0oWWBdOJtpooA7BXRzU/s320/Untitled2.png" width="158" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
I have also tested the code against iPhone 8 (a Non-Notch iPhone), and it appears normal. So this is pretty much a perfect easy solution. But of course, to use the safeArea, you need at least iOS11, which I think is a good minimum iOS requirement as of now. iOS version adoption rate is quite high.&lt;br /&gt;
&lt;br /&gt;
But ah... just noticed the admob banner is covering the menu bar at the bottom :D that is another issue that I need to fix. You see why it is good to write a blog now, you get to debug your code at the same time too. Hahaha!&lt;br /&gt;
&lt;br /&gt;
This tutorial has no downloadable Project because.... it's just some code sharing really.&lt;br /&gt;
&lt;br /&gt;
Ok guys. That's all. Thanks for reading.&lt;/div&gt;
</description><link>http://xcodenoobies.blogspot.com/2019/02/how-to-update-your-old-spritekit-game.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJmfUY4KiwCyv2drXsXP0MEEi9Y-8QU5x71rIYhWtwCO91BHmpEMtJXHO43yOkdcIEACwzwGFedx-74fnVwJfWK27EhWK5MliE5-TV4XXmAGLA9i4VXhADEny6wmaNAM8uBS7nBvqohiU/s72-c/Caution.jpg" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-3077758267473150522</guid><pubDate>Sat, 18 Nov 2017 09:03:00 +0000</pubDate><atom:updated>2019-12-31T03:33:43.987-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">api</category><category domain="http://www.blogger.com/atom/ns#">example</category><category domain="http://www.blogger.com/atom/ns#">iamja77</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">iphone</category><category domain="http://www.blogger.com/atom/ns#">iphone8</category><category domain="http://www.blogger.com/atom/ns#">iphonex</category><category domain="http://www.blogger.com/atom/ns#">nsurlsession</category><category domain="http://www.blogger.com/atom/ns#">public</category><category domain="http://www.blogger.com/atom/ns#">simulator</category><category domain="http://www.blogger.com/atom/ns#">tutorial</category><category domain="http://www.blogger.com/atom/ns#">weather</category><category domain="http://www.blogger.com/atom/ns#">webservice</category><category domain="http://www.blogger.com/atom/ns#">x</category><title>How To: Make an App That Uses Public API (Openweathermap.org) Using NSURLSession</title><description>I think I mentioned somewhere (and maybe everywhere) that I love &lt;b&gt;&lt;span style="color: #e06666;"&gt;J&lt;/span&gt;&lt;/b&gt;SON. I LOVE IT! JSON is basically like NSDictionary. Every entry has a key and a value. And you can go nesting too - like a dictionary of dictionary of dictionary. O_o&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDHDaMz0V0mlX0L3GL9PE91aJMDrGvsm5QHo27YLqGXhSOCJZUWPi8Vb1cpZGAQXRcLmsn44gJT6d1ixsT0eoZ7i7oXUSRrQh48-2gfE1ryjad7GBMWoUFbdOxqXy7WBvt3pEX_7FsXa8/s1600/images.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="183" data-original-width="275" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDHDaMz0V0mlX0L3GL9PE91aJMDrGvsm5QHo27YLqGXhSOCJZUWPi8Vb1cpZGAQXRcLmsn44gJT6d1ixsT0eoZ7i7oXUSRrQh48-2gfE1ryjad7GBMWoUFbdOxqXy7WBvt3pEX_7FsXa8/s1600/images.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
// this is a bird's nest&lt;/div&gt;
&lt;br /&gt;
What we're going to make:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3PCM6lJKbhBww5nRiwy9jX0aFz2yztgsV-gb3OP8mixcBbNHFcDOLEfdp8UoGWIwvvLcTqwD5XfvmjKB-1D0oZB6y4iqeSUa2doWPg71rolaIL11C0VdLtkBRSObx7vsR43JKj1X0obE/s1600/Nov-18-2017+17-00-27.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="847" data-original-width="481" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3PCM6lJKbhBww5nRiwy9jX0aFz2yztgsV-gb3OP8mixcBbNHFcDOLEfdp8UoGWIwvvLcTqwD5XfvmjKB-1D0oZB6y4iqeSUa2doWPg71rolaIL11C0VdLtkBRSObx7vsR43JKj1X0obE/s320/Nov-18-2017+17-00-27.gif" width="181" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
2.5MB GIF&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
JSON is structured and that is why many web service opts to this format for communication between a client and server. In the old days, or even now, some web service still use obscure format like user-defined text strings separated by pipes or commas (CSV). Something like:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://www.dropbox.com/s/gccmz1rbgqzfs2e/WeatherAPI.zip?dl=0"&gt;&lt;img border="0" data-original-height="69" data-original-width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJxG0OiR4I5cgBN5SVtYoQvK4JjHyT-EsRjiDs6Mu8MH_mPgcSoDbpQmPK6jn8bpdTw9vdrj_QZ24_lqOwr8DvRqS-s7KRYw1egiWp1QcukVoy7tu3bEdU1myqnW_nrXXm7gdhunCWdy8/s320/download.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq"&gt;
1,Q,London,23.7,22.6,22.3&lt;br /&gt;
2,Q,Tokyo,13.7,12.6,12.3&lt;br /&gt;
3,Q,Kuala Lumpur,28.7,32.6,32.3&lt;/blockquote&gt;
&lt;div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjneaNQeWiIMO_3CO5nRqIsDe9JDhDYgSFSUy2AWoHfZYFqUjPeZp8FZbTI6R_YtzrtHHY4xcE0zBb_T7DESHvnwr-10O57ITnzSksankCxq4xm0ro4JaKJfgzXp6wuyepVkObYd077geQ/s1600/download.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="464" data-original-width="620" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjneaNQeWiIMO_3CO5nRqIsDe9JDhDYgSFSUy2AWoHfZYFqUjPeZp8FZbTI6R_YtzrtHHY4xcE0zBb_T7DESHvnwr-10O57ITnzSksankCxq4xm0ro4JaKJfgzXp6wuyepVkObYd077geQ/s320/download.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You get the response and process it by splitting it by LFCR (Linefeed(newline) or Carriage Return - \n or \r) and further processing each lines by splitting it with commas. It can get complex. And can easily break if any column data suddenly has a comma in it. Or some server system only print out \n only or \r only. All sorts of unforeseeable problems in that department! In short, fuck that shit. haha.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
And that is why most Public APIs uses JSON (or XML which is what PLIST are) to send data to a request from a client. In this tutorial, we will make a weather app by connecting to a FREE (free stuffs are groovy) weather API service called openweathermap.org.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
First, as you would've guessed, you need to register an account at &lt;a href="http://openweathermap.org/"&gt;openweathermap.org&lt;/a&gt;. Go ahead and do that it's free. Once you've registered, log in and go to the API tab to get your API KEY. Most API calls require API key. It serves as the identification of the API caller (ie your app). There are some public APIs that don't require key (Twitter previously don't require API key either but now they do :\, and NASA too offers API without API key - those people at NASA are so nice. :D). I actually has one app that uses their MODIS Satellite data using their cool API, called HazeToday. It plots the hot spots (mostly fire) on the map and I also use another API from China to plot pollution index on the map.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Anyway, API Key normally looks like this:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;style type="text/css"&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545}
&lt;/style&gt;


&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
f2c2dfdcf3d0e1e40f5ddff65f580a62&lt;/blockquote&gt;
&lt;br /&gt;
A long string of hexadecimal number. &lt;b&gt;Obviously this is not my key. And it is also not your key. It is just an example of how the key look like.&lt;/b&gt; You need to copy your own key in the API tabs page of openweathermap.org and append it to your API url later on.&lt;br /&gt;
&lt;br /&gt;
So let us create our Project in XCode. Choose a single viewcontroller template. Give it a name and when the project has been created, open the Storyboard and put two labels on it and change the appearance to be something like the image below. First label text is "0.0°C" and second label with a smaller font size with text "--" (two dashes). Remember to add the constraints.&lt;br /&gt;
&lt;br /&gt;
After that, connect the 2 labels to their IBOutlets. Next lets add a picker with a list of famous cities in the world. Lets make it such that we can select a city and have the current temperature of that city shown on it. For this purpose, drop a UIPickerView on it and add constraints and connect the IBOutlet, datasource and delegate. Connect IBOutlet to the picker and add the UIPickerViewDelegate and UIPickerViewDataSource to the interface. You'll end up with something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMv8Lels9nfSK2Cc3sAppvEbyJ14Vxi_Fb8i6Jzvou1FNT3EwcTjzprbzVPz2dgMQD1uuxtLSNuobBK-84OahDiYBijzu01raeDB9fam3JYNTCYv_2WAXJHqkY2ET7Ig7pkyPCNzWw5Uc/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="555" data-original-width="310" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMv8Lels9nfSK2Cc3sAppvEbyJ14Vxi_Fb8i6Jzvou1FNT3EwcTjzprbzVPz2dgMQD1uuxtLSNuobBK-84OahDiYBijzu01raeDB9fam3JYNTCYv_2WAXJHqkY2ET7Ig7pkyPCNzWw5Uc/s400/Untitled.png" width="222" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
Our State-of-the-art UI :P&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Now, we need to declare an NSArray to hold the city list. For this tutorial purposes, the array is going to be static, if you need it to be expandable, or read from a file/server, you may change it to NSMutableArray and add cities to it programatically.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Your ViewController.h should now look like this:&lt;/div&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;

@interface ViewController : UIViewController &amp;lt;UIPickerViewDelegate, UIPickerViewDataSource&amp;gt;
@property (weak, nonatomic) IBOutlet UILabel *tempLabel;
@property (weak, nonatomic) IBOutlet UILabel *cityLabel;
@property (weak, nonatomic) IBOutlet UIPickerView *cityPicker;
@property (nonatomic, strong) NSArray *cityArray;

@end
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets create the cityArray in viewDidLoad with some cities.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
Note: If you create your data in viewDidLoad, you do not need to reload components of the pickerview as the pickerview sets its dataSource AFTER viewDidLoad.&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
self.cityArray = [NSArray arrayWithObjects:@"London",@"Tokyo",@"Jakarta",
@"California", @"Taiwan", @"Seoul",@"Delhi",@"Istanbul", @"Beijing", nil];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Next lets add the PickerView delegate methods and link our dataSource cityArray to it:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    
}

-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    return [_cityArray objectAtIndex:row];
}

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return [_cityArray count];
}

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
If you run the app now, you will get a list of the city populated in the PickerView nicely. Check it out in the *ahem*, iPhone X simulator (lol that notch so fugly).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtjwdCirNfWcWNSTfiggAK4eSv-bk2_7F9npdWn05u7akLfpSdPOTYYVQDzfkeP_PNW4Xrr_TS8w2ogSfh-9mNHQO9uwOtqmnJ_6J3I_EV5VVoGCcV8QlVwi7xK1JAtMHEB1mRJ4yIMKM/s1600/11111.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="865" data-original-width="450" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtjwdCirNfWcWNSTfiggAK4eSv-bk2_7F9npdWn05u7akLfpSdPOTYYVQDzfkeP_PNW4Xrr_TS8w2ogSfh-9mNHQO9uwOtqmnJ_6J3I_EV5VVoGCcV8QlVwi7xK1JAtMHEB1mRJ4yIMKM/s400/11111.png" width="207" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
You can also scroll it and select a particular city. But nothing happens yet because our "didSelectRow" delegate is empty. What we need to do now is call the API when user selected a city. So lets create a custom method and construct an NSURLSession dataTask to request an API call to OpenWeatherMap.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
There are many NSURLSession functions, namely downloadDataTask, dataTask, uploadDataTask, etc. NSURLSession is relatively new Apple API, before this developers use NSURLConnection. The advantage of NSURLSession is that it is an NSOperationQueue itself. So we can set its behaviour, or by default it will run serially. NSURLSession manages itself better and you should use it from now on.&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
-(void)getWeatherForCity:(NSString*)city {
    

    NSString *APIurl = [NSString stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather?APPID=%@&amp;amp;q=%@",API_KEY,city];
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:APIurl]
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                
                                                
                                                
                                            }];
    [dataTask resume];
    
}
&lt;/code&gt;&lt;/pre&gt;
Note that writing &amp;nbsp;NSURLSessionDataTask *dataTask = ... merely sets the session up and what to do when it is completed but it is not being triggered until you call&lt;span style="font-family: &amp;quot;times&amp;quot;; white-space: normal;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: red; color: white; font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; white-space: normal;"&gt;[dataTask resume];&lt;/span&gt;&lt;b style="font-family: Times; white-space: normal;"&gt;&amp;nbsp;One could easily miss this and be wondering why the code isn't working.&lt;/b&gt;
&lt;br /&gt;
Lets break this down piece by piece:&lt;br /&gt;
&lt;br /&gt;
First of all, we need to construct the URL for the API call. Most public APIs follow the same format for GET method - [MAIN URL]/[API]?key=[YOUR_API_KEY]&amp;amp;param1=a&amp;amp;param2=b But it really depends on the API provider they can use any format they want. For POST method, the construct is a little different because the parameters are not inside the URL, instead it is embedded inside the request Command.&lt;br /&gt;
&lt;br /&gt;
In our case,&lt;br /&gt;
[API] = weather&lt;br /&gt;
key = API_KEY&lt;br /&gt;
param1 = q&lt;br /&gt;
param2 = not available.&lt;br /&gt;
&lt;br /&gt;
So with a simple NSString formatting, we can assign these to our string URL. A quick NSLog of APIurl should yield:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&amp;amp;q=London&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Copying and pasting this to the browser, you should see some json results printed on your browser.
But remember to replace YOUR_API_KEY with your hexadecimal key string otherwise it won't work.

&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyzhLpaI1634I2x7JHMDGj4hVVGEWXeEjZoBGAWZse7AHrW7_acFTJgL4D_g4nvmyXdaeQOaLXD9tDBW3R0Nlo1Qpsv_UP9ScD5rmuASOTcKMCjfAML3qUIuxi7lNnXxv1XUNXDZN6kaU/s1600/Untitled2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="201" data-original-width="1119" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyzhLpaI1634I2x7JHMDGj4hVVGEWXeEjZoBGAWZse7AHrW7_acFTJgL4D_g4nvmyXdaeQOaLXD9tDBW3R0Nlo1Qpsv_UP9ScD5rmuASOTcKMCjfAML3qUIuxi7lNnXxv1XUNXDZN6kaU/s640/Untitled2.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
The above image shows how to test your API call with browser if it uses "GET" method. Note you cannot test "POST" method using browser, you may take a look at the app &lt;a href="https://www.getpostman.com/"&gt;Postman&lt;/a&gt; to do that. Now lets write didSelectRow method. We need to retrieve the string in the pickerview and attach it to our getWeatherForCity: parameter.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    
    NSString * selectedCity = [_cityArray objectAtIndex:row];
    [self getWeatherForCity:selectedCity];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Now the session call code is done, lets see it work. Don't worry about the completion block code yet. What we need to do now is check whether our NSURLSession works or not. We can do this by adding NSLog to the completion block to see the response from the server to our simulator. Add it and now our code should look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt; NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:APIurl]
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                
                                                NSLog(@"RESPONSE: %@",response.description);
                                                
                                            }];&lt;/code&gt;&lt;/pre&gt;
Lets run our app in simulator and check the console log.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
IMPORTANT: If your public API uses &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;http&lt;/span&gt; instead of &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;https&lt;/span&gt;, your call will be blocked by the iOS. You need to add a little settings in the Info.plist. (App Transport Security key). You can read here for more information:&amp;nbsp;&lt;a href="https://stackoverflow.com/questions/31254725/transport-security-has-blocked-a-cleartext-http"&gt;https://stackoverflow.com/questions/31254725/transport-security-has-blocked-a-cleartext-http&lt;/a&gt;&lt;/blockquote&gt;
&lt;br /&gt;
If your API call is not blocked and if your internet is working fine, when you select a City from the pickerview, you will see a response from the server:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLXx42hHx7UDoBAi-Ru-dMCAd_epRRvIWhJ7GjWjwwQlPaNtsJkCgQ8gfNvd7zJfJ2Ntnntelci-QoJ-PlEFBJ0-FMWlkV0oZ9ICB6AZZwikCzJ98w8DRUQqsYSDs2CTgT5KmQgRapfn0/s1600/response.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="416" data-original-width="845" height="314" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLXx42hHx7UDoBAi-Ru-dMCAd_epRRvIWhJ7GjWjwwQlPaNtsJkCgQ8gfNvd7zJfJ2Ntnntelci-QoJ-PlEFBJ0-FMWlkV0oZ9ICB6AZZwikCzJ98w8DRUQqsYSDs2CTgT5KmQgRapfn0/s640/response.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
A response from server normally indicates the status of your call. A server may decline your call, due to several reasons, such as wrong parameters set, or other server related errors. The response from Openweathermap is one of the best response I have ever seen. It reports, status code (400 = successful), and lots of info in the header - supported call methods (GET/POST), and etc). Normally we don't use these, except for status code, so we can handle the response in our app - for example, if the response is successful, then we read the data and display, but if the response code is other than code 400, we may display an alert to user "Server error, please try again later"... or something like that.&lt;br /&gt;
&lt;br /&gt;
Another way to do this is to simply check for the error returned. If it is nil, then it could be successful, or it could be timed out. That is entirely up to the developer which to choose. For our tutorial, lets assume the server always replies with code 400 (ie successful) and the error is always nil. So we can immediately process the data received.&lt;br /&gt;
&lt;br /&gt;
The data sent by the server is string encoded as NSData, so we need a way to convert this data (which is binary format) into a string. We do this by using an available iOS API call of NSString class method &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;initWithData: encoding:&lt;/span&gt;&lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt; &lt;/span&gt;Lets add &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSLog&lt;/span&gt; again, but this time to display our converted data. Your getWeatherForCity now looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
-(void)getWeatherForCity:(NSString*)city {
    
    
    NSString *APIurl = [NSString stringWithFormat:@"https://api.openweathermap.org/data/2.5/weather?APPID=%@&amp;amp;q=%@",K_API_KEY,city];
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:APIurl]
                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                
                 NSString* dataStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
                NSLog(@"Result: %@", dataStr);
                                                
                                                
                }];
    [dataTask resume];
    
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming no errors for both cases, when we run the app, and selecting a city, we will get the result:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR6YOlsjnF2aWTcRBzquc4CQeRyMVILxTWAUehFbz8n2zKRPg8uugU_TVtI5y1XFqWLqy0Ddo_cRQlbV8fEMHgdQFWhUK2K7vRsBfsyx7gH70PAw93jrJwsBdxEkKJrXnV3SwgO_LWH_Q/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="156" data-original-width="857" height="115" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR6YOlsjnF2aWTcRBzquc4CQeRyMVILxTWAUehFbz8n2zKRPg8uugU_TVtI5y1XFqWLqy0Ddo_cRQlbV8fEMHgdQFWhUK2K7vRsBfsyx7gH70PAw93jrJwsBdxEkKJrXnV3SwgO_LWH_Q/s640/3.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
GREAT! Now we have this json in string format we can process it and pick which data we want to display. As you can see, there are quite many data available here, but we're going to display one only and that is "temp" data tucked inside the json structure. When you see this structure, you might freak out. But don't. Instead copy it and paste in &lt;a href="http://jsonviewer.stack.hu/"&gt;http://jsonviewer.stack.hu/&lt;/a&gt;. Then click on the Viewer tab, you will be able to view the data structure better:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbr260p3_wM5UxcAWpQiSYkcd52cQQBrl5nwKP362tqM7V_Sw5q69U_wPzDuYFUUxop-LJgTBUB0mvuaXpk9_W1vbAf_nVbMiU5aeT9TlGxyJ4BA3P-xQb0UfJzFW6xnNGwkZGjfJX4HE/s1600/json.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="452" data-original-width="403" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbr260p3_wM5UxcAWpQiSYkcd52cQQBrl5nwKP362tqM7V_Sw5q69U_wPzDuYFUUxop-LJgTBUB0mvuaXpk9_W1vbAf_nVbMiU5aeT9TlGxyJ4BA3P-xQb0UfJzFW6xnNGwkZGjfJX4HE/s640/json.png" width="570" /&gt;&lt;/a&gt;&lt;/div&gt;
Nice right??? JSON format is basically NSDictionary. It has a "key" and "value" pair. For our case, we need to get the "main" key, where the content is another dictionary, and we can retrieve the value of temperature, at the "temp" key. But what we have now is only string format, how do we convert this string of json structure into NSDictionary? Enter the code below:&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;

NSData * jsonData = [dataStr dataUsingEncoding:NSASCIIStringEncoding];
NSError * error=nil;
NSDictionary * parsedDict = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&amp;amp;error];                               

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Now we can use parsedDict, traverse into the temp key and get the value and display.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
NSDictionary *mainDict = [parsedData objectForKey:@"main"];
_tempLabel.text = [mainDict objectForKey:@"temp"];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
If you run it, you probably will have a crash. LOL! What's wrong? Firstly, take a good look at the JSON format in the online viewer. temp holds a number. That means, the returned object of key "temp" is an &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSNumber&lt;/span&gt; and not an &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSString&lt;/span&gt;. An example of &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSString&lt;/span&gt; object in the json is in the "name" key which is "Tokyo". Whatever that is inside a double quote, that is safe to assume that it is a &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSString&lt;/span&gt;. Otherwise it is an &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSNumber&lt;/span&gt; especially the data is a number like 23.5, or 35.&amp;nbsp; And by logical thinking, for example a data of 456F is an &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSString&lt;/span&gt; even if it does not have a doublequotes. Thus we need to change our code:&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
NSDictionary *mainDict = [parsedData objectForKey:@"main"];
NSNumber *tempNum = [mainDict objectForKey:@"temp"];
dispatch_async(dispatch_get_main_queue(), ^{
      _tempLabel.text = [NSString stringWithFormat:@"%.1f°C", [tempNum floatValue]];
});
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Whoa. What's going on in this code? It is quite simple, except the dispatch part. First we assign the object from "temp" key to an NSNumber variable. Then we format it as a NSString and assign it to our label. That is pretty much it. %.1f format indicates we want a floating number with 1 decimal place. And suffix it with °C. Note, we also convert the NSNumber to a float first before supplying it to our string formatter.&lt;br /&gt;
&lt;br /&gt;
So what is the dispatch thingy? It is a useful function to grab the main thread. As a general rule in software design, any update to the UI, must be done on the main thread. But our NSURLSession is a thread that runs in the background, thus if we want to udpate the UI in its block, we need to call the main thread and that's what dispatch thingy does.&lt;br /&gt;
&lt;br /&gt;
Go ahead and run the app you will get the value displayed in the label when you select a city:&lt;br /&gt;
&lt;br /&gt;
&lt;img border="0" data-original-height="1600" data-original-width="739" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaRgLnY20IvjckGYoFRF1hK26bo5K7M7HCQQS2udJuf0VEgmx1ut9zm5xFfrOuQF5h7_hlEo5aJzBVcD95lFpg5WQETBMxs1s5oETjsgqqIOFf7frzq1uXLI5ZUU9fgJED_UKgwmqaeoo/s320/Simulator+Screen+Shot+-+iPhone+X+-+2017-11-18+at+16.00.49.png" width="147" /&gt;

&lt;img border="0" data-original-height="1600" data-original-width="739" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFcRsW7bNtDdqjetrzgHbO9NLqYidM-DxPwys9Bem3aJDxfAw5A5s2IJsGem_Z-J8_Gsdj-eIsmrGcC9ch4bGKD6L3uaaBDkGxR04vCnEkVqH4k0pgfRYB1ZoTGB-MAiCAO_iZSEMoZNE/s320/Simulator+Screen+Shot+-+iPhone+X+-+2017-11-18+at+16.00.55.png" width="147" /&gt;
&lt;br /&gt;
&lt;br /&gt;
But wait, why is the temperature so high? 277 deg Celcius in London?? People will burn! Oh wait. Checks on openweathermap.org shows that temperature is in Kelvin. So we need to convert the number from Kelvin to Celcius using the formula:&lt;br /&gt;
&lt;br /&gt;
&lt;i style="background-color: #fffff8; box-sizing: border-box; color: #222222; font-family: &amp;quot;Times New Roman&amp;quot;; font-size: 24px;"&gt;T&lt;/i&gt;&lt;sub style="background-color: #fffff8; box-sizing: border-box; color: #222222; font-family: &amp;quot;Times New Roman&amp;quot;;"&gt;(°C)&lt;/sub&gt;&lt;span style="background-color: #fffff8; color: #222222; font-family: &amp;quot;times new roman&amp;quot;; font-size: 24px;"&gt;&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;i style="background-color: #fffff8; box-sizing: border-box; color: #222222; font-family: &amp;quot;Times New Roman&amp;quot;; font-size: 24px;"&gt;T&lt;/i&gt;&lt;sub style="background-color: #fffff8; box-sizing: border-box; color: #222222; font-family: &amp;quot;Times New Roman&amp;quot;;"&gt;(K)&lt;/sub&gt;&lt;span style="background-color: #fffff8; color: #222222; font-family: &amp;quot;times new roman&amp;quot;; font-size: 24px;"&gt;&amp;nbsp;- 273.15&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Translating that to code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
float tempFloatK = [tempNum floatValue];
float tempFloatC = tempFloatK - 273.15;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
What about the City label? You have 2 options here. One is to set it directly from the pickerview,&amp;nbsp; or you can get it from "name" key in the json data. Lets just get it from json data. Add the following code to the getWeatherForCity method (bolded code is newly added):&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-C"&gt;
NSDictionary *mainDict = [parsedData objectForKey:@"main"];
NSNumber *tempNum = [mainDict objectForKey:@"temp"];
                    
&lt;b&gt;float tempFloatK = [tempNum floatValue];
float tempFloatC = tempFloatK - 273.15;
NSString *cityStr = [parsedData objectForKey:@"name"];&lt;/b&gt;
                    
dispatch_async(dispatch_get_main_queue(), ^{
       _tempLabel.text = [NSString stringWithFormat:@"%.1f°C", tempFloatC];
       &lt;b&gt;_cityLabel.text = cityStr;&lt;/b&gt;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Now when you run the app, selecting a city, will show the temperature and city name underneath it. We're done! Below is the GIF of the app in action.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://www.dropbox.com/s/hgmrgj2zo3tgxdb/BunnyPart1.zip?dl=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="847" data-original-width="481" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3PCM6lJKbhBww5nRiwy9jX0aFz2yztgsV-gb3OP8mixcBbNHFcDOLEfdp8UoGWIwvvLcTqwD5XfvmjKB-1D0oZB6y4iqeSUa2doWPg71rolaIL11C0VdLtkBRSObx7vsR43JKj1X0obE/s320/Nov-18-2017+17-00-27.gif" width="181" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Further considerations: If you want to make this into an app, there are more things to consider:&lt;br /&gt;
1. A "loading" indicator right after a user selects a city.&lt;br /&gt;
2. Error messages if there is no internet&lt;br /&gt;
3. Error messages if the server is not returning any data or any other server related error&lt;br /&gt;
4. You can add more data to display since the server returns quite a handful of data.&lt;br /&gt;
5. Other cool features: Adding animations, nice pictures, even links to video of the city.&lt;br /&gt;
&lt;br /&gt;
With that, we conclude our tutorial! Thanks fam.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://www.dropbox.com/s/gccmz1rbgqzfs2e/WeatherAPI.zip?dl=0"&gt;&lt;img border="0" data-original-height="69" data-original-width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJxG0OiR4I5cgBN5SVtYoQvK4JjHyT-EsRjiDs6Mu8MH_mPgcSoDbpQmPK6jn8bpdTw9vdrj_QZ24_lqOwr8DvRqS-s7KRYw1egiWp1QcukVoy7tu3bEdU1myqnW_nrXXm7gdhunCWdy8/s320/download.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://xcodenoobies.blogspot.com/2017/11/how-to-make-app-that-uses-public-api.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDHDaMz0V0mlX0L3GL9PE91aJMDrGvsm5QHo27YLqGXhSOCJZUWPi8Vb1cpZGAQXRcLmsn44gJT6d1ixsT0eoZ7i7oXUSRrQh48-2gfE1ryjad7GBMWoUFbdOxqXy7WBvt3pEX_7FsXa8/s72-c/images.jpg" width="72"/><thr:total>3</thr:total><enclosure length="-1" type="application/json" url="https://www.dropbox.com/s/gccmz1rbgqzfs2e/WeatherAPI.zip?dl=0"/><itunes:explicit/><itunes:subtitle>I think I mentioned somewhere (and maybe everywhere) that I love JSON. I LOVE IT! JSON is basically like NSDictionary. Every entry has a key and a value. And you can go nesting too - like a dictionary of dictionary of dictionary. O_o // this is a bird's nest What we're going to make: 2.5MB GIF JSON is structured and that is why many web service opts to this format for communication between a client and server. In the old days, or even now, some web service still use obscure format like user-defined text strings separated by pipes or commas (CSV). Something like: 1,Q,London,23.7,22.6,22.3 2,Q,Tokyo,13.7,12.6,12.3 3,Q,Kuala Lumpur,28.7,32.6,32.3 You get the response and process it by splitting it by LFCR (Linefeed(newline) or Carriage Return - \n or \r) and further processing each lines by splitting it with commas. It can get complex. And can easily break if any column data suddenly has a comma in it. Or some server system only print out \n only or \r only. All sorts of unforeseeable problems in that department! In short, fuck that shit. haha. And that is why most Public APIs uses JSON (or XML which is what PLIST are) to send data to a request from a client. In this tutorial, we will make a weather app by connecting to a FREE (free stuffs are groovy) weather API service called openweathermap.org. First, as you would've guessed, you need to register an account at openweathermap.org. Go ahead and do that it's free. Once you've registered, log in and go to the API tab to get your API KEY. Most API calls require API key. It serves as the identification of the API caller (ie your app). There are some public APIs that don't require key (Twitter previously don't require API key either but now they do :\, and NASA too offers API without API key - those people at NASA are so nice. :D). I actually has one app that uses their MODIS Satellite data using their cool API, called HazeToday. It plots the hot spots (mostly fire) on the map and I also use another API from China to plot pollution index on the map. Anyway, API Key normally looks like this: p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545} f2c2dfdcf3d0e1e40f5ddff65f580a62 A long string of hexadecimal number. Obviously this is not my key. And it is also not your key. It is just an example of how the key look like. You need to copy your own key in the API tabs page of openweathermap.org and append it to your API url later on. So let us create our Project in XCode. Choose a single viewcontroller template. Give it a name and when the project has been created, open the Storyboard and put two labels on it and change the appearance to be something like the image below. First label text is "0.0°C" and second label with a smaller font size with text "--" (two dashes). Remember to add the constraints. After that, connect the 2 labels to their IBOutlets. Next lets add a picker with a list of famous cities in the world. Lets make it such that we can select a city and have the current temperature of that city shown on it. For this purpose, drop a UIPickerView on it and add constraints and connect the IBOutlet, datasource and delegate. Connect IBOutlet to the picker and add the UIPickerViewDelegate and UIPickerViewDataSource to the interface. You'll end up with something like this: Our State-of-the-art UI :P Now, we need to declare an NSArray to hold the city list. For this tutorial purposes, the array is going to be static, if you need it to be expandable, or read from a file/server, you may change it to NSMutableArray and add cities to it programatically. Your ViewController.h should now look like this: @interface ViewController : UIViewController &amp;lt;UIPickerViewDelegate, UIPickerViewDataSource&amp;gt; @property (weak, nonatomic) IBOutlet UILabel *tempLabel; @property (weak, nonatomic) IBOutlet UILabel *cityLabel; @property (weak, nonatomic) IBOutlet UIPickerView *cityPicker; @property (nonatomic, strong) NSArray *cityArray; @end Lets create the cityArray in viewDidLoad with some cities. Note: If you create your data in viewDidLoad, you do not need to reload components of the pickerview as the pickerview sets its dataSource AFTER viewDidLoad. self.cityArray = [NSArray arrayWithObjects:@"London",@"Tokyo",@"Jakarta", @"California", @"Taiwan", @"Seoul",@"Delhi",@"Istanbul", @"Beijing", nil]; Next lets add the PickerView delegate methods and link our dataSource cityArray to it: -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { } -(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { return [_cityArray objectAtIndex:row]; } -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return [_cityArray count]; } -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; } If you run the app now, you will get a list of the city populated in the PickerView nicely. Check it out in the *ahem*, iPhone X simulator (lol that notch so fugly). You can also scroll it and select a particular city. But nothing happens yet because our "didSelectRow" delegate is empty. What we need to do now is call the API when user selected a city. So lets create a custom method and construct an NSURLSession dataTask to request an API call to OpenWeatherMap. There are many NSURLSession functions, namely downloadDataTask, dataTask, uploadDataTask, etc. NSURLSession is relatively new Apple API, before this developers use NSURLConnection. The advantage of NSURLSession is that it is an NSOperationQueue itself. So we can set its behaviour, or by default it will run serially. NSURLSession manages itself better and you should use it from now on. -(void)getWeatherForCity:(NSString*)city { NSString *APIurl = [NSString stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather?APPID=%@&amp;amp;q=%@",API_KEY,city]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:APIurl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { }]; [dataTask resume]; } Note that writing &amp;nbsp;NSURLSessionDataTask *dataTask = ... merely sets the session up and what to do when it is completed but it is not being triggered until you call&amp;nbsp;[dataTask resume];&amp;nbsp;One could easily miss this and be wondering why the code isn't working. Lets break this down piece by piece: First of all, we need to construct the URL for the API call. Most public APIs follow the same format for GET method - [MAIN URL]/[API]?key=[YOUR_API_KEY]&amp;amp;param1=a&amp;amp;param2=b But it really depends on the API provider they can use any format they want. For POST method, the construct is a little different because the parameters are not inside the URL, instead it is embedded inside the request Command. In our case, [API] = weather key = API_KEY param1 = q param2 = not available. So with a simple NSString formatting, we can assign these to our string URL. A quick NSLog of APIurl should yield: http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&amp;amp;q=London Copying and pasting this to the browser, you should see some json results printed on your browser. But remember to replace YOUR_API_KEY with your hexadecimal key string otherwise it won't work. The above image shows how to test your API call with browser if it uses "GET" method. Note you cannot test "POST" method using browser, you may take a look at the app Postman to do that. Now lets write didSelectRow method. We need to retrieve the string in the pickerview and attach it to our getWeatherForCity: parameter. -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { NSString * selectedCity = [_cityArray objectAtIndex:row]; [self getWeatherForCity:selectedCity]; } Now the session call code is done, lets see it work. Don't worry about the completion block code yet. What we need to do now is check whether our NSURLSession works or not. We can do this by adding NSLog to the completion block to see the response from the server to our simulator. Add it and now our code should look like this: NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:APIurl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSLog(@"RESPONSE: %@",response.description); }]; Lets run our app in simulator and check the console log. IMPORTANT: If your public API uses http instead of https, your call will be blocked by the iOS. You need to add a little settings in the Info.plist. (App Transport Security key). You can read here for more information:&amp;nbsp;https://stackoverflow.com/questions/31254725/transport-security-has-blocked-a-cleartext-http If your API call is not blocked and if your internet is working fine, when you select a City from the pickerview, you will see a response from the server: A response from server normally indicates the status of your call. A server may decline your call, due to several reasons, such as wrong parameters set, or other server related errors. The response from Openweathermap is one of the best response I have ever seen. It reports, status code (400 = successful), and lots of info in the header - supported call methods (GET/POST), and etc). Normally we don't use these, except for status code, so we can handle the response in our app - for example, if the response is successful, then we read the data and display, but if the response code is other than code 400, we may display an alert to user "Server error, please try again later"... or something like that. Another way to do this is to simply check for the error returned. If it is nil, then it could be successful, or it could be timed out. That is entirely up to the developer which to choose. For our tutorial, lets assume the server always replies with code 400 (ie successful) and the error is always nil. So we can immediately process the data received. The data sent by the server is string encoded as NSData, so we need a way to convert this data (which is binary format) into a string. We do this by using an available iOS API call of NSString class method initWithData: encoding: Lets add NSLog again, but this time to display our converted data. Your getWeatherForCity now looks like this: -(void)getWeatherForCity:(NSString*)city { NSString *APIurl = [NSString stringWithFormat:@"https://api.openweathermap.org/data/2.5/weather?APPID=%@&amp;amp;q=%@",K_API_KEY,city]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:APIurl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSString* dataStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; NSLog(@"Result: %@", dataStr); }]; [dataTask resume]; } Assuming no errors for both cases, when we run the app, and selecting a city, we will get the result: GREAT! Now we have this json in string format we can process it and pick which data we want to display. As you can see, there are quite many data available here, but we're going to display one only and that is "temp" data tucked inside the json structure. When you see this structure, you might freak out. But don't. Instead copy it and paste in http://jsonviewer.stack.hu/. Then click on the Viewer tab, you will be able to view the data structure better: Nice right??? JSON format is basically NSDictionary. It has a "key" and "value" pair. For our case, we need to get the "main" key, where the content is another dictionary, and we can retrieve the value of temperature, at the "temp" key. But what we have now is only string format, how do we convert this string of json structure into NSDictionary? Enter the code below: NSData * jsonData = [dataStr dataUsingEncoding:NSASCIIStringEncoding]; NSError * error=nil; NSDictionary * parsedDict = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&amp;amp;error]; Now we can use parsedDict, traverse into the temp key and get the value and display. NSDictionary *mainDict = [parsedData objectForKey:@"main"]; _tempLabel.text = [mainDict objectForKey:@"temp"]; If you run it, you probably will have a crash. LOL! What's wrong? Firstly, take a good look at the JSON format in the online viewer. temp holds a number. That means, the returned object of key "temp" is an NSNumber and not an NSString. An example of NSString object in the json is in the "name" key which is "Tokyo". Whatever that is inside a double quote, that is safe to assume that it is a NSString. Otherwise it is an NSNumber especially the data is a number like 23.5, or 35.&amp;nbsp; And by logical thinking, for example a data of 456F is an NSString even if it does not have a doublequotes. Thus we need to change our code: NSDictionary *mainDict = [parsedData objectForKey:@"main"]; NSNumber *tempNum = [mainDict objectForKey:@"temp"]; dispatch_async(dispatch_get_main_queue(), ^{ _tempLabel.text = [NSString stringWithFormat:@"%.1f°C", [tempNum floatValue]]; }); Whoa. What's going on in this code? It is quite simple, except the dispatch part. First we assign the object from "temp" key to an NSNumber variable. Then we format it as a NSString and assign it to our label. That is pretty much it. %.1f format indicates we want a floating number with 1 decimal place. And suffix it with °C. Note, we also convert the NSNumber to a float first before supplying it to our string formatter. So what is the dispatch thingy? It is a useful function to grab the main thread. As a general rule in software design, any update to the UI, must be done on the main thread. But our NSURLSession is a thread that runs in the background, thus if we want to udpate the UI in its block, we need to call the main thread and that's what dispatch thingy does. Go ahead and run the app you will get the value displayed in the label when you select a city: But wait, why is the temperature so high? 277 deg Celcius in London?? People will burn! Oh wait. Checks on openweathermap.org shows that temperature is in Kelvin. So we need to convert the number from Kelvin to Celcius using the formula: T(°C)&amp;nbsp;=&amp;nbsp;T(K)&amp;nbsp;- 273.15 Translating that to code: float tempFloatK = [tempNum floatValue]; float tempFloatC = tempFloatK - 273.15; What about the City label? You have 2 options here. One is to set it directly from the pickerview,&amp;nbsp; or you can get it from "name" key in the json data. Lets just get it from json data. Add the following code to the getWeatherForCity method (bolded code is newly added): NSDictionary *mainDict = [parsedData objectForKey:@"main"]; NSNumber *tempNum = [mainDict objectForKey:@"temp"]; float tempFloatK = [tempNum floatValue]; float tempFloatC = tempFloatK - 273.15; NSString *cityStr = [parsedData objectForKey:@"name"]; dispatch_async(dispatch_get_main_queue(), ^{ _tempLabel.text = [NSString stringWithFormat:@"%.1f°C", tempFloatC]; _cityLabel.text = cityStr; }); Now when you run the app, selecting a city, will show the temperature and city name underneath it. We're done! Below is the GIF of the app in action. Further considerations: If you want to make this into an app, there are more things to consider: 1. A "loading" indicator right after a user selects a city. 2. Error messages if there is no internet 3. Error messages if the server is not returning any data or any other server related error 4. You can add more data to display since the server returns quite a handful of data. 5. Other cool features: Adding animations, nice pictures, even links to video of the city. With that, we conclude our tutorial! Thanks fam.</itunes:subtitle><itunes:author>noreply@blogger.com (GeneCode)</itunes:author><itunes:summary>I think I mentioned somewhere (and maybe everywhere) that I love JSON. I LOVE IT! JSON is basically like NSDictionary. Every entry has a key and a value. And you can go nesting too - like a dictionary of dictionary of dictionary. O_o // this is a bird's nest What we're going to make: 2.5MB GIF JSON is structured and that is why many web service opts to this format for communication between a client and server. In the old days, or even now, some web service still use obscure format like user-defined text strings separated by pipes or commas (CSV). Something like: 1,Q,London,23.7,22.6,22.3 2,Q,Tokyo,13.7,12.6,12.3 3,Q,Kuala Lumpur,28.7,32.6,32.3 You get the response and process it by splitting it by LFCR (Linefeed(newline) or Carriage Return - \n or \r) and further processing each lines by splitting it with commas. It can get complex. And can easily break if any column data suddenly has a comma in it. Or some server system only print out \n only or \r only. All sorts of unforeseeable problems in that department! In short, fuck that shit. haha. And that is why most Public APIs uses JSON (or XML which is what PLIST are) to send data to a request from a client. In this tutorial, we will make a weather app by connecting to a FREE (free stuffs are groovy) weather API service called openweathermap.org. First, as you would've guessed, you need to register an account at openweathermap.org. Go ahead and do that it's free. Once you've registered, log in and go to the API tab to get your API KEY. Most API calls require API key. It serves as the identification of the API caller (ie your app). There are some public APIs that don't require key (Twitter previously don't require API key either but now they do :\, and NASA too offers API without API key - those people at NASA are so nice. :D). I actually has one app that uses their MODIS Satellite data using their cool API, called HazeToday. It plots the hot spots (mostly fire) on the map and I also use another API from China to plot pollution index on the map. Anyway, API Key normally looks like this: p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545} f2c2dfdcf3d0e1e40f5ddff65f580a62 A long string of hexadecimal number. Obviously this is not my key. And it is also not your key. It is just an example of how the key look like. You need to copy your own key in the API tabs page of openweathermap.org and append it to your API url later on. So let us create our Project in XCode. Choose a single viewcontroller template. Give it a name and when the project has been created, open the Storyboard and put two labels on it and change the appearance to be something like the image below. First label text is "0.0°C" and second label with a smaller font size with text "--" (two dashes). Remember to add the constraints. After that, connect the 2 labels to their IBOutlets. Next lets add a picker with a list of famous cities in the world. Lets make it such that we can select a city and have the current temperature of that city shown on it. For this purpose, drop a UIPickerView on it and add constraints and connect the IBOutlet, datasource and delegate. Connect IBOutlet to the picker and add the UIPickerViewDelegate and UIPickerViewDataSource to the interface. You'll end up with something like this: Our State-of-the-art UI :P Now, we need to declare an NSArray to hold the city list. For this tutorial purposes, the array is going to be static, if you need it to be expandable, or read from a file/server, you may change it to NSMutableArray and add cities to it programatically. Your ViewController.h should now look like this: @interface ViewController : UIViewController &amp;lt;UIPickerViewDelegate, UIPickerViewDataSource&amp;gt; @property (weak, nonatomic) IBOutlet UILabel *tempLabel; @property (weak, nonatomic) IBOutlet UILabel *cityLabel; @property (weak, nonatomic) IBOutlet UIPickerView *cityPicker; @property (nonatomic, strong) NSArray *cityArray; @end Lets create the cityArray in viewDidLoad with some cities. Note: If you create your data in viewDidLoad, you do not need to reload components of the pickerview as the pickerview sets its dataSource AFTER viewDidLoad. self.cityArray = [NSArray arrayWithObjects:@"London",@"Tokyo",@"Jakarta", @"California", @"Taiwan", @"Seoul",@"Delhi",@"Istanbul", @"Beijing", nil]; Next lets add the PickerView delegate methods and link our dataSource cityArray to it: -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { } -(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { return [_cityArray objectAtIndex:row]; } -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return [_cityArray count]; } -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; } If you run the app now, you will get a list of the city populated in the PickerView nicely. Check it out in the *ahem*, iPhone X simulator (lol that notch so fugly). You can also scroll it and select a particular city. But nothing happens yet because our "didSelectRow" delegate is empty. What we need to do now is call the API when user selected a city. So lets create a custom method and construct an NSURLSession dataTask to request an API call to OpenWeatherMap. There are many NSURLSession functions, namely downloadDataTask, dataTask, uploadDataTask, etc. NSURLSession is relatively new Apple API, before this developers use NSURLConnection. The advantage of NSURLSession is that it is an NSOperationQueue itself. So we can set its behaviour, or by default it will run serially. NSURLSession manages itself better and you should use it from now on. -(void)getWeatherForCity:(NSString*)city { NSString *APIurl = [NSString stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather?APPID=%@&amp;amp;q=%@",API_KEY,city]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:APIurl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { }]; [dataTask resume]; } Note that writing &amp;nbsp;NSURLSessionDataTask *dataTask = ... merely sets the session up and what to do when it is completed but it is not being triggered until you call&amp;nbsp;[dataTask resume];&amp;nbsp;One could easily miss this and be wondering why the code isn't working. Lets break this down piece by piece: First of all, we need to construct the URL for the API call. Most public APIs follow the same format for GET method - [MAIN URL]/[API]?key=[YOUR_API_KEY]&amp;amp;param1=a&amp;amp;param2=b But it really depends on the API provider they can use any format they want. For POST method, the construct is a little different because the parameters are not inside the URL, instead it is embedded inside the request Command. In our case, [API] = weather key = API_KEY param1 = q param2 = not available. So with a simple NSString formatting, we can assign these to our string URL. A quick NSLog of APIurl should yield: http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&amp;amp;q=London Copying and pasting this to the browser, you should see some json results printed on your browser. But remember to replace YOUR_API_KEY with your hexadecimal key string otherwise it won't work. The above image shows how to test your API call with browser if it uses "GET" method. Note you cannot test "POST" method using browser, you may take a look at the app Postman to do that. Now lets write didSelectRow method. We need to retrieve the string in the pickerview and attach it to our getWeatherForCity: parameter. -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { NSString * selectedCity = [_cityArray objectAtIndex:row]; [self getWeatherForCity:selectedCity]; } Now the session call code is done, lets see it work. Don't worry about the completion block code yet. What we need to do now is check whether our NSURLSession works or not. We can do this by adding NSLog to the completion block to see the response from the server to our simulator. Add it and now our code should look like this: NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:APIurl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSLog(@"RESPONSE: %@",response.description); }]; Lets run our app in simulator and check the console log. IMPORTANT: If your public API uses http instead of https, your call will be blocked by the iOS. You need to add a little settings in the Info.plist. (App Transport Security key). You can read here for more information:&amp;nbsp;https://stackoverflow.com/questions/31254725/transport-security-has-blocked-a-cleartext-http If your API call is not blocked and if your internet is working fine, when you select a City from the pickerview, you will see a response from the server: A response from server normally indicates the status of your call. A server may decline your call, due to several reasons, such as wrong parameters set, or other server related errors. The response from Openweathermap is one of the best response I have ever seen. It reports, status code (400 = successful), and lots of info in the header - supported call methods (GET/POST), and etc). Normally we don't use these, except for status code, so we can handle the response in our app - for example, if the response is successful, then we read the data and display, but if the response code is other than code 400, we may display an alert to user "Server error, please try again later"... or something like that. Another way to do this is to simply check for the error returned. If it is nil, then it could be successful, or it could be timed out. That is entirely up to the developer which to choose. For our tutorial, lets assume the server always replies with code 400 (ie successful) and the error is always nil. So we can immediately process the data received. The data sent by the server is string encoded as NSData, so we need a way to convert this data (which is binary format) into a string. We do this by using an available iOS API call of NSString class method initWithData: encoding: Lets add NSLog again, but this time to display our converted data. Your getWeatherForCity now looks like this: -(void)getWeatherForCity:(NSString*)city { NSString *APIurl = [NSString stringWithFormat:@"https://api.openweathermap.org/data/2.5/weather?APPID=%@&amp;amp;q=%@",K_API_KEY,city]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:APIurl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSString* dataStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; NSLog(@"Result: %@", dataStr); }]; [dataTask resume]; } Assuming no errors for both cases, when we run the app, and selecting a city, we will get the result: GREAT! Now we have this json in string format we can process it and pick which data we want to display. As you can see, there are quite many data available here, but we're going to display one only and that is "temp" data tucked inside the json structure. When you see this structure, you might freak out. But don't. Instead copy it and paste in http://jsonviewer.stack.hu/. Then click on the Viewer tab, you will be able to view the data structure better: Nice right??? JSON format is basically NSDictionary. It has a "key" and "value" pair. For our case, we need to get the "main" key, where the content is another dictionary, and we can retrieve the value of temperature, at the "temp" key. But what we have now is only string format, how do we convert this string of json structure into NSDictionary? Enter the code below: NSData * jsonData = [dataStr dataUsingEncoding:NSASCIIStringEncoding]; NSError * error=nil; NSDictionary * parsedDict = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&amp;amp;error]; Now we can use parsedDict, traverse into the temp key and get the value and display. NSDictionary *mainDict = [parsedData objectForKey:@"main"]; _tempLabel.text = [mainDict objectForKey:@"temp"]; If you run it, you probably will have a crash. LOL! What's wrong? Firstly, take a good look at the JSON format in the online viewer. temp holds a number. That means, the returned object of key "temp" is an NSNumber and not an NSString. An example of NSString object in the json is in the "name" key which is "Tokyo". Whatever that is inside a double quote, that is safe to assume that it is a NSString. Otherwise it is an NSNumber especially the data is a number like 23.5, or 35.&amp;nbsp; And by logical thinking, for example a data of 456F is an NSString even if it does not have a doublequotes. Thus we need to change our code: NSDictionary *mainDict = [parsedData objectForKey:@"main"]; NSNumber *tempNum = [mainDict objectForKey:@"temp"]; dispatch_async(dispatch_get_main_queue(), ^{ _tempLabel.text = [NSString stringWithFormat:@"%.1f°C", [tempNum floatValue]]; }); Whoa. What's going on in this code? It is quite simple, except the dispatch part. First we assign the object from "temp" key to an NSNumber variable. Then we format it as a NSString and assign it to our label. That is pretty much it. %.1f format indicates we want a floating number with 1 decimal place. And suffix it with °C. Note, we also convert the NSNumber to a float first before supplying it to our string formatter. So what is the dispatch thingy? It is a useful function to grab the main thread. As a general rule in software design, any update to the UI, must be done on the main thread. But our NSURLSession is a thread that runs in the background, thus if we want to udpate the UI in its block, we need to call the main thread and that's what dispatch thingy does. Go ahead and run the app you will get the value displayed in the label when you select a city: But wait, why is the temperature so high? 277 deg Celcius in London?? People will burn! Oh wait. Checks on openweathermap.org shows that temperature is in Kelvin. So we need to convert the number from Kelvin to Celcius using the formula: T(°C)&amp;nbsp;=&amp;nbsp;T(K)&amp;nbsp;- 273.15 Translating that to code: float tempFloatK = [tempNum floatValue]; float tempFloatC = tempFloatK - 273.15; What about the City label? You have 2 options here. One is to set it directly from the pickerview,&amp;nbsp; or you can get it from "name" key in the json data. Lets just get it from json data. Add the following code to the getWeatherForCity method (bolded code is newly added): NSDictionary *mainDict = [parsedData objectForKey:@"main"]; NSNumber *tempNum = [mainDict objectForKey:@"temp"]; float tempFloatK = [tempNum floatValue]; float tempFloatC = tempFloatK - 273.15; NSString *cityStr = [parsedData objectForKey:@"name"]; dispatch_async(dispatch_get_main_queue(), ^{ _tempLabel.text = [NSString stringWithFormat:@"%.1f°C", tempFloatC]; _cityLabel.text = cityStr; }); Now when you run the app, selecting a city, will show the temperature and city name underneath it. We're done! Below is the GIF of the app in action. Further considerations: If you want to make this into an app, there are more things to consider: 1. A "loading" indicator right after a user selects a city. 2. Error messages if there is no internet 3. Error messages if the server is not returning any data or any other server related error 4. You can add more data to display since the server returns quite a handful of data. 5. Other cool features: Adding animations, nice pictures, even links to video of the city. With that, we conclude our tutorial! Thanks fam.</itunes:summary><itunes:keywords>api, example, iamja77, ios, iphone, iphone8, iphonex, nsurlsession, public, simulator, tutorial, weather, webservice, x</itunes:keywords></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-5174124091655233698</guid><pubDate>Tue, 07 Nov 2017 11:36:00 +0000</pubDate><atom:updated>2017-11-17T21:12:46.221-08:00</atom:updated><title>More Contribution to XCode Community!</title><description>One of my friends asked me, you get a lot of revenue from writing tutorial blog? My answer is - NO. I get like 0.001 cents per day from my blog currently lol. My blog isn't famous like appcoda or raywenderlich. So why do I keep on doing it? Simple - I always view that anything I learn, is an inspiration that is meant to be shared to everyone. I do it because I love to share what I know. Often, I faced with a problem to do something in my own apps, and upon finding a solution I like to document it, because I am sure others might have the same problem or obstacle. By sharing what I found or created, we advance together.&lt;br /&gt;
&lt;br /&gt;
Enough intro. Anyway this post is a short one. I just want to announce yet another contribution that I am making towards the XCode Community - MY FIRST EVER GITHUB REPO!!!! OMG! Sorry I am too excited for this.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0OVJUtJZUnrFrPCsU7IZR5jPtdK_M94VmTLR0edeJ0QzBs0V9zOm7C4xWBRu-Mo7Y6aSfrREKLahEXTh9EC_hgywoADJJNmLtBI2sAxx_Yp6SOaB7cJ7PmL3ctd3chKLdHz4NsG-6ai0/s1600/source.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="281" data-original-width="500" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0OVJUtJZUnrFrPCsU7IZR5jPtdK_M94VmTLR0edeJ0QzBs0V9zOm7C4xWBRu-Mo7Y6aSfrREKLahEXTh9EC_hgywoADJJNmLtBI2sAxx_Yp6SOaB7cJ7PmL3ctd3chKLdHz4NsG-6ai0/s400/source.gif" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
First repo is a flexible Toolbar/Tabbar. I have added a list of my Github repo in the left bar for future reference. Well, that's about it for this blogpost. I am thinking to redo the Switchy object as a proper repo next. Stay tune. Or not. Whatever dude and dudette.&lt;br /&gt;
&lt;br /&gt;
Ps. I forgot to put the link to my main GITHUB REPO: &lt;a href="https://github.com/gene-code/"&gt;GENECODE GITHUB&lt;/a&gt;</description><link>http://xcodenoobies.blogspot.com/2017/11/more-contribution-to-xcode-community.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0OVJUtJZUnrFrPCsU7IZR5jPtdK_M94VmTLR0edeJ0QzBs0V9zOm7C4xWBRu-Mo7Y6aSfrREKLahEXTh9EC_hgywoADJJNmLtBI2sAxx_Yp6SOaB7cJ7PmL3ctd3chKLdHz4NsG-6ai0/s72-c/source.gif" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-733045434013655521</guid><pubDate>Sun, 05 Nov 2017 02:14:00 +0000</pubDate><atom:updated>2017-11-17T21:19:21.883-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">beginner</category><category domain="http://www.blogger.com/atom/ns#">delegates</category><category domain="http://www.blogger.com/atom/ns#">guide</category><category domain="http://www.blogger.com/atom/ns#">iamja77</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">newbie</category><category domain="http://www.blogger.com/atom/ns#">obj-c</category><category domain="http://www.blogger.com/atom/ns#">objective c</category><category domain="http://www.blogger.com/atom/ns#">reusables</category><category domain="http://www.blogger.com/atom/ns#">uicollectionview</category><category domain="http://www.blogger.com/atom/ns#">uitableview</category><title>How To: Use Reusable Views Correctly (TableView, CollectionView, etc)</title><description>First, some short intro! :D My blog views has finally reached ONE MILLION!!!&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi62mCKS6R05jQYEwXiymomEYLq31h4f95P8F1D-drdV7Nwb4ZFyggxfq1FVKGf1gX-hSbnklSNvYFiXRmemmJbCZhTXY6DwBvnwEXM_StnhWFhvKB7WyRA31PmrMi2xY6ay2KvRD9-fD4/s1600/download.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="167" data-original-width="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi62mCKS6R05jQYEwXiymomEYLq31h4f95P8F1D-drdV7Nwb4ZFyggxfq1FVKGf1gX-hSbnklSNvYFiXRmemmJbCZhTXY6DwBvnwEXM_StnhWFhvKB7WyRA31PmrMi2xY6ay2KvRD9-fD4/s1600/download.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Now if I get a dollar for a view. Phew! None the less, I am so happy with this view count- why? Because it means I helped quite many developers to create their apps (hopefully). And those apps will benefit mankind. Even if it's a fart app, hey, it cheers up people and that is good.&lt;br /&gt;
&lt;br /&gt;
As noobs we tend to not getting the whole picture of a particular UI object. A label is simple, there is text property, you set it directly in Storyboard or programatically (&lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;label.text = @"hello";&lt;/span&gt;)&amp;nbsp;and it shows immediately. Pretty straight forward. But for objects that uses Reusable Cells like TableView, there are multiple set ups that we need to do to use it properly and therefore prevent any weird and unwanted bugs and crashes. Anyway here's what we're gonna end up with at the end of the tutorial:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNYF3LhetQo_SHf1kV-W6LDzLwqk8s4qkhMNgnY2FmbgWoqp_2e8VhwKuNqbuMQCBjZl7C-_ZOnrfGVZMZsQvCOvZs0tSUbReA9YHdKS9ddDUbmuAkAxckWTHls1lj54bB71_Po4gjD5Q/s1600/Nov-05-2017+10-05-11.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="529" data-original-width="320" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNYF3LhetQo_SHf1kV-W6LDzLwqk8s4qkhMNgnY2FmbgWoqp_2e8VhwKuNqbuMQCBjZl7C-_ZOnrfGVZMZsQvCOvZs0tSUbReA9YHdKS9ddDUbmuAkAxckWTHls1lj54bB71_Po4gjD5Q/s320/Nov-05-2017+10-05-11.gif" width="193" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
It's a 2.4MB GIF.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What does Reusable Views mean?&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It is basically a concept/method to display big amount of data in a scrollable area. In case of TableView, &amp;nbsp;the amount of cells being created by TableView is only a small quantity that is enough to fit the visible area of TableView.&lt;br /&gt;
&lt;br /&gt;
For example, if you have TableView of height 300, and each cells height is 10, then at least 31 cells are created at runtime. And when you scroll down the table, the cell that is being pushed out of view&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;at the top is moved to the bottom and its content is updated according to the datasource (code in &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;cellForRow&lt;/span&gt; delegate). This is how Reusable Views work. And it is same thing with CollectionView or other objects or custom libraries with Reusable things. So no matter how much data you have, the amount of cells that exist in memory is only 31, at least.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://www.dropbox.com/s/8mqtxc5su282roi/Reusables.zip?dl=0"&gt;&lt;img border="0" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJxG0OiR4I5cgBN5SVtYoQvK4JjHyT-EsRjiDs6Mu8MH_mPgcSoDbpQmPK6jn8bpdTw9vdrj_QZ24_lqOwr8DvRqS-s7KRYw1egiWp1QcukVoy7tu3bEdU1myqnW_nrXXm7gdhunCWdy8/s320/download.png" width="320" /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that you understand this concept, you can code more efficiently and be able to code safely around it. Before we start to write code for our TableView example, we need to understand another concept that is MVC which means &lt;b&gt;Model-View-Controller.&lt;/b&gt; We need to write code that comply with this concept and to do this we have to keep things separate.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The MVC Concept&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In case of TableView, our &lt;b&gt;Model &lt;/b&gt;is our dataSource. Our &lt;b&gt;View &lt;/b&gt;is the TableView object in storyboard obviously. And our &lt;b&gt;Controller&lt;/b&gt; is all the delegates functions. Our job is to create our Model that complies to our intention of the View behaviour, and connect Model and View with Controller. In normal English, we need to create our datasource (ie &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSArray&lt;/span&gt;/&lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSMutableArray&lt;/span&gt;) that has all the necessary properties of the things in our cell and pass it to our delegates.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Lets Do It&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Lets make a tableview that lists down a menu for a restaurant with details of the dish in each rows. Such UI is typical in many applications. How do we go about in designing this feature?&lt;br /&gt;
&lt;br /&gt;
We need to create a custom object to work with. Our datasource will be an array containing these objects. So we need to decide what is the contents of our cell item. You can use dictionaries but trust me, objects is the way to go. Objects make coding a lot simpler and cleaner.&lt;br /&gt;
&lt;br /&gt;
So I will split the process into the corresponding "section" of the design pattern:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #3d85c6;"&gt;a) &lt;b&gt;MODEL&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #990000;"&gt;b) &lt;b&gt;VIEW&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #6aa84f;"&gt;c) &lt;b&gt;CONTROLLER&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
But we'll start with VIEW first, since it's more fun. :P&lt;br /&gt;
&lt;h2&gt;
&lt;br /&gt;&lt;b&gt;&lt;span style="color: #cc0000;"&gt;Setting Up The "VIEW"&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
First, drag and drop a &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UITableView&lt;/span&gt; on your empty &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;ViewController&lt;/span&gt;. Set the constraints. I leave it up to you how big you want the tableview to be. For me, I just size it up to fill the entire view. And then I drag the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UITableViewCell&lt;/span&gt; object into the tableview. You should have something like the following.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMKo3M77HCVUZ6BIrerk7jUqmWGAWpo6OT2W0Ojl1MseChdSqXgpmynHLc_1F9XwZKxTvU0BtNOJPqOlkwngqylGbRQimTfWHf63v-s-IoYPcqf9YOlBoT84x1ebCTtdCX2a5gjSMJGfg/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="746" data-original-width="518" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMKo3M77HCVUZ6BIrerk7jUqmWGAWpo6OT2W0Ojl1MseChdSqXgpmynHLc_1F9XwZKxTvU0BtNOJPqOlkwngqylGbRQimTfWHf63v-s-IoYPcqf9YOlBoT84x1ebCTtdCX2a5gjSMJGfg/s320/Untitled.png" width="222" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&amp;nbsp;Lets review our plan for the tableview cell (which is empty now):&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Menu photo - (a &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UIImageView&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;Menu name - (a &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UILabel&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;Price - (another &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UILabel&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;An icon if it is chef recommendation or not. (a &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UIImageView&lt;/span&gt;)&lt;/li&gt;
&lt;/ol&gt;
So lets add these items to our empty cell. I made the cell bigger by dragging the bottom edge of the cell downwards. Then adding all the items and arrange them as needed and set the corresponding constraints. I also changed the cell background color just for fun. Here's what I ended up with:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjen9wCYBR0yR99cLbyisZFyXJv_6TCuh7ipTcFTcxUepBT7VcwA2Rik87Yg3wiCwzYDMLTw0kDVL8Z_pzyFCeszC8J8BVR4vC1OZhGiZSfM_AvR1vQnTGq-ihLrJtfXLJkFD10i5bS2CQ/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="182" data-original-width="422" height="138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjen9wCYBR0yR99cLbyisZFyXJv_6TCuh7ipTcFTcxUepBT7VcwA2Rik87Yg3wiCwzYDMLTw0kDVL8Z_pzyFCeszC8J8BVR4vC1OZhGiZSfM_AvR1vQnTGq-ihLrJtfXLJkFD10i5bS2CQ/s320/Untitled.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Next, we need to link the cell to our viewController.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
If your table contents are simple, like a single text for each cell, you do not need to customize the cell class and you can skip the next step and just use the default cell style class like Basic, Left Detail, Right Detail or Subtitle.&amp;nbsp;&lt;/blockquote&gt;
&lt;br /&gt;
To customize cell class, right click on your &lt;i&gt;Project Navigator&lt;/i&gt; and select &lt;i&gt;New File...&lt;/i&gt; then specify the creation of a custom &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UITableViewCell&lt;/span&gt; as shown in image below. I named this custom class &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;MenuTableViewCell&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGK6fVBUXmUU0nzs7OP1j4thRFhhrgMzuw0NDQMU9Ur2jC22bWQA2DYc1S5l9k93vYHCQVw8c5iw1PYi376PnJrEUy8AxDqWhA_jMOaaXrZryukiguWy7vVt1j3cHZ_8XN4x_pADV_hds/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="526" data-original-width="735" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGK6fVBUXmUU0nzs7OP1j4thRFhhrgMzuw0NDQMU9Ur2jC22bWQA2DYc1S5l9k93vYHCQVw8c5iw1PYi376PnJrEUy8AxDqWhA_jMOaaXrZryukiguWy7vVt1j3cHZ_8XN4x_pADV_hds/s400/Untitled.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
Now goto Storyboard and click on the tableview cell, and in the &lt;i&gt;Identity Inspector,&lt;/i&gt; in Class textfield, key in the name of your custom cell class that you created above. In this case, &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;MenuTableViewCell&lt;/span&gt;. This is a crucial step and if you miss it (many noobs do miss it, including me :D), you won't be able to connect the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;IBOutlet&lt;/span&gt; to the class header.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhawOI2iYY_ATGto0VEZEcDuhrQxhSVNasxAFyvdiKHdEZUdBAPAnNL2sFSUAMur8AKDT-OOjk67dsIoHtTQZtLos4ZyTkCYcmdWSesigeFdw7RKQmoMGYXw1KFwHyV_GBhqb60h8I5pQ8/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="327" data-original-width="790" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhawOI2iYY_ATGto0VEZEcDuhrQxhSVNasxAFyvdiKHdEZUdBAPAnNL2sFSUAMur8AKDT-OOjk67dsIoHtTQZtLos4ZyTkCYcmdWSesigeFdw7RKQmoMGYXw1KFwHyV_GBhqb60h8I5pQ8/s640/Untitled.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
And then, connect all the objects in your cell to the class header. Give it meaningful names. Here is the completed header of the cell class:&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
//
//  MenuTableViewCell.h
//  Reusables
//
//  Created by Emir Fithri on 03/11/2017.
//  Copyright © 2017 geneCode. All rights reserved.
//

#import &lt;uikit it.h=""&gt;

@interface MenuTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIImageView *menuImg;
@property (weak, nonatomic) IBOutlet UILabel *menuName;
@property (weak, nonatomic) IBOutlet UIImageView *menuIcon;
@property (weak, nonatomic) IBOutlet UILabel *menuPrice;

@end
&lt;/uikit&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Next, return to storyboard and click on the TableView cell and at the &lt;i&gt;Attributes Inspector &lt;/i&gt;key in the Identifier of your custom cell. This is very important. For this example, I named it simply &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;menuCellID&lt;/span&gt;. The ID is used by the TableView to distinguish if your table has multiple type of cells styles. Leave &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;MenuTableViewCell.m&lt;/span&gt; as it is.&lt;br /&gt;
&lt;br /&gt;
At this point, your custom TableView cell is completed and this concludes setting up the "View" part! Congrats :D&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVqPZ5HHSKEUg5w8w1fOnytc1rT75cVqZsYn4FDTRUbO1-Pam-emkCEENdCJtY-UjKWw3ZalR0K9ohmpOs258nrcrhh71mq5Gwy0HLP2cQynuHc9vkx-IPeHjqgRmLpJmM85VXER-YIXY/s1600/download-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="226" data-original-width="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVqPZ5HHSKEUg5w8w1fOnytc1rT75cVqZsYn4FDTRUbO1-Pam-emkCEENdCJtY-UjKWw3ZalR0K9ohmpOs258nrcrhh71mq5Gwy0HLP2cQynuHc9vkx-IPeHjqgRmLpJmM85VXER-YIXY/s1600/download-1.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;b&gt;&lt;span style="color: #3d85c6;"&gt;Setting Up The "MODEL"&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
Our Model is a collection of Objects in &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSMutableArray&lt;/span&gt;. You could use &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSDictionary &lt;/span&gt;as objects to store in the array, but custom objects will make coding a whole lot easier and cleaner.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWBPr6eaCAZJX-mpTMieFJdxWJL7TZuIWtPLf8owqgO1rOfI2lR4m5IuezkGsGaXQSRZYrtyw-FdjWZ2_BAEpFDyVh7GTZlvDqkCQ2kboWkaKA8Ht6dTunPHzAMlggTFaPE_znSWun7M8/s1600/model.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="202" data-original-width="399" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWBPr6eaCAZJX-mpTMieFJdxWJL7TZuIWtPLf8owqgO1rOfI2lR4m5IuezkGsGaXQSRZYrtyw-FdjWZ2_BAEpFDyVh7GTZlvDqkCQ2kboWkaKA8Ht6dTunPHzAMlggTFaPE_znSWun7M8/s320/model.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
Some options of our Model&lt;/div&gt;
&lt;br /&gt;
So lets code our custom object first. In XCode, right click the project navigator on the left and add a new class. Name it &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;MenuItem&lt;/span&gt;. Add the properties according to the details that we are going to add in the cell into the header file. Then create a standard init method for the class in .m file. We will end up as below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;//
//  MenuItem.h
//  Reusables
//
//  Created by Emir Fithri on 03/11/2017.
//  Copyright © 2017 geneCode. All rights reserved.
//

#import &amp;lt;foundation.h&amp;gt;

@interface MenuItem : NSObject

@property (nonatomic, strong) NSString *menuImgName, *menuName, *menuPrice;
@property (nonatomic, assign) int menuCode;


-(id)init;

@end
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

//
//  MenuItem.m
//  Reusables
//
//  Created by Emir Fithri on 03/11/2017.
//  Copyright © 2017 geneCode. All rights reserved.
//

#import "MenuItem.h"

@implementation MenuItem

-(id)init {
    self = [super init];
    if (self) {
        // you can initialize your properties here if needed
    }
    return self;
}

@end
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
Now to complete setting up our "Model", we need to declare our &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NSMutableArray&lt;/span&gt; to hold the menu objects, in the viewcontroller's header file:&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
@property (nonatomic, strong) NSMutableArray *menuArray;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Finally lets create the menu objects and fill them into the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;menuArray&lt;/span&gt;. We can do this in &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;viewDidLoad&lt;/span&gt;. Remember to &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;#import "MenuItem.h"&lt;/span&gt; in the viewController's header so we can use the class.&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

-(void)viewDidLoad {     
      [super viewDidLoad];     
    MenuItem *menu1 = [[MenuItem alloc] init];
    menu1.menuName= @"Fish &amp;amp; Chips";
    menu1.menuImgName = @"menu1.jpg";
    menu1.menuPrice = @"12.99";
    menu1.menuCode = 1;
    
    MenuItem *menu2 = [[MenuItem alloc] init];
    menu2.menuName= @"Hamburger";
    menu2.menuImgName = @"menu2.jpg";
    menu2.menuPrice = @"8.99";
    menu2.menuCode = 1;
    
    MenuItem *menu3 = [[MenuItem alloc] init];
    menu3.menuName= @"Beef Steak";
    menu3.menuImgName = @"menu3.jpg";
    menu3.menuPrice = @"21.59";
    menu3.menuCode = 2;

    MenuItem *menu4 = [[MenuItem alloc] init];
    menu4.menuName= @"Cappucino";
    menu4.menuImgName = @"menu4.jpg";
    menu4.menuPrice = @"1.99";
    menu4.menuCode = 1;
    
    MenuItem *menu5 = [[MenuItem alloc] init];
    menu5.menuName= @"Banana Split";
    menu5.menuImgName = @"menu5.jpg";
    menu5.menuPrice = @"11.29";
    menu5.menuCode = 1;
    
    MenuItem *menu6 = [[MenuItem alloc] init];
    menu6.menuName= @"Hot Dog";
    menu6.menuImgName = @"menu6.jpg";
    menu6.menuPrice = @"4.59";
    menu6.menuCode = 2;
    
    MenuItem *menu7 = [[MenuItem alloc] init];
    menu7.menuName= @"Grilled Chicken";
    menu7.menuImgName = @"menu7.jpg";
    menu7.menuPrice = @"25.59";
    menu7.menuCode = 1;
    
    MenuItem *menu8 = [[MenuItem alloc] init];
    menu8.menuName= @"Ice Lemon Tea";
    menu8.menuImgName = @"menu8.jpg";
    menu8.menuPrice = @"1.59";
    menu8.menuCode = 1;

      //initialize our array
      _menuArray = [[NSMutableArray alloc] init];
      [_menuArray addObject:menu1];
      [_menuArray addObject:menu2];
      [_menuArray addObject:menu3];
      [_menuArray addObject:menu4];
      [_menuArray addObject:menu5];
      [_menuArray addObject:menu6];
      [_menuArray addObject:menu7];
      [_menuArray addObject:menu8];
}

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
In this example, I added only 8 menu items. If you're feeling adventurous, you can go ahead and add as much items as you want. And the code I use is to make you easily understand the process so they are not simplified and not factored in anyway. You can simplify the code for menu item creation by creating your own class method in MenuItem.m, so you can simply call&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
  [_menuArray addObject:[MenuItem createWithName:@"Beef Steak" photo:@"menu1.jpg" price:@"21.59" code:2]];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
I already covered about class methods and functions in previous tutorial: &lt;a href="https://xcodenoobies.blogspot.my/2017/07/how-to-basic-of-xcode-methods-functions.html"&gt;Basic of XCode Methods &amp;amp; Functions in Objective C&lt;/a&gt;. Do read it if you want to know more. And finally, of course, we have to add all our actual data (menu images, and icons). You can add them in the Asset folder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With that, we have completed setting up the "MODEL" part.&lt;br /&gt;
&lt;h2&gt;
&lt;span style="color: #6aa84f;"&gt;&lt;br /&gt;&lt;b&gt;Setting Up The "CONTROLLER"&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
Now here is where the functionality comes in. A Controller for any reusable views basically consists of delegates functions and dataSource link. Some developer or tutorials refers this to "&lt;i&gt;Protocol&lt;/i&gt;". It means the same thing. Although, if we want to be concise, we can say that &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UITableView&lt;/span&gt; implements the Protocol, and our class that uses the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UITableView&lt;/span&gt;'s protocol, implements its delegates. You can open up a &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;UITableView.h&lt;/span&gt; and see it for yourself:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD-0rREWSGgpCV4Bzcc4ltMUS5WpIRDsN_pqT4waYrpELXbWvqaWLIli8X6kVelR7KV4_7OsF-r6pRqL8UufuAhYLijAGNz631x2k5VtNkAPRbQ0Fhph14IbE1EThnx01jbKtlapaq6Cg/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="337" data-original-width="551" height="388" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD-0rREWSGgpCV4Bzcc4ltMUS5WpIRDsN_pqT4waYrpELXbWvqaWLIli8X6kVelR7KV4_7OsF-r6pRqL8UufuAhYLijAGNz631x2k5VtNkAPRbQ0Fhph14IbE1EThnx01jbKtlapaq6Cg/s640/Untitled.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This is how a class implements a protocol for other class to adopt and use. Get it?&lt;br /&gt;
&lt;br /&gt;
As you probably have noticed, we have not connected our TableView to any &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;IBOutlet&lt;/span&gt; yet. Now is the time to do so. And not only that you also have to connect other things on the TableView: In total we need to hook up 3 things:&lt;br /&gt;
&lt;br /&gt;
i) IBOutlet&lt;br /&gt;
ii) Datasource&lt;br /&gt;
iii) Delegate&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ILKwbRTEBy7Rd6iN-iJejQfeUp-1ws5XJKPIJGkN8sUPXmjOfiDPUfvR3JWAttqWWbecYAO8BF4IE035nU4VBmB2sis3edtec6dEGdGz5apZSUFp2trVolx68cUpXATB_-SWQh1JCZc/s1600/Screen+Shot+2017-11-04+at+12.08.18+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="403" data-original-width="931" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ILKwbRTEBy7Rd6iN-iJejQfeUp-1ws5XJKPIJGkN8sUPXmjOfiDPUfvR3JWAttqWWbecYAO8BF4IE035nU4VBmB2sis3edtec6dEGdGz5apZSUFp2trVolx68cUpXATB_-SWQh1JCZc/s640/Screen+Shot+2017-11-04+at+12.08.18+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The above picture shows how to connect the dataSource of the TableView to the ViewController. Repeat this process for "delegate" underneath it. Then connect the TableView's &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;IBOutlet&lt;/span&gt; (New Referencing Outlet) to the ViewController's header. This basically tells the iOS where it can find the delegate functions and the data for this tableView (which is in ViewController).&lt;br /&gt;
&lt;br /&gt;
Next, open up the ViewController's header file and "implement the tableview delegate and datasource".&amp;nbsp; Basically now we need to add Delegate and Datasource in our class because that's what our UI is looking for when we run the app. To do this, just add &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;&amp;lt;UITableViewDelegate, UITableViewDataSource&amp;gt;&lt;/span&gt; in the header file. Your header will now look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
//
//  ViewController.h
//  Reusables
//
//  Created by Emir Fithri on 03/11/2017.
//  Copyright © 2017 geneCode. All rights reserved.
//

#import &amp;lt;UIKit.h&amp;gt;
#import "MenuItem.h"

@interface ViewController : UIViewController &amp;lt;UITableViewDelegate, UITableViewDataSource&amp;gt;

@property (nonatomic, strong) NSMutableArray *menuArray;
@property (weak, nonatomic) IBOutlet UITableView *menuTable;

@end
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Next goto the ViewController.m file and you can now enter the delegate functions of TableView. You can start to type -(void)table... and you will see code completion pops up a list of all the relevant delegate functions that you can use for the TableView. (If you don't, try hitting ESC button at the end of your typing.)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPjIsxmRWT3gNiJiWLS0O3D911DfL1VBm4OlU3M8Bsj8TjKUjxImmu7chZr59p5gNyMT-xsgV94Psd1_clAcQ05PJORVqegOPMpmZfM8668WDBkAMMntolAF2QpOJ8cXwgl9XHrj5EJaQ/s1600/Screen+Shot+2017-11-04+at+12.27.24+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="497" data-original-width="796" height="398" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPjIsxmRWT3gNiJiWLS0O3D911DfL1VBm4OlU3M8Bsj8TjKUjxImmu7chZr59p5gNyMT-xsgV94Psd1_clAcQ05PJORVqegOPMpmZfM8668WDBkAMMntolAF2QpOJ8cXwgl9XHrj5EJaQ/s640/Screen+Shot+2017-11-04+at+12.27.24+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
And that is just a list of delegates that of the type "void". There are delegates of other types too, like NSInteger, CGFloat, and so on. Good news is, you DO NOT HAVE to implement all of these delegate function to make our table work! &lt;b&gt;I'd say the minimum is 3 delegate functions:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
// TableView Delegates
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
 
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
       
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The first delegate is to set our cell height. Eventhough we have manually changed the cell size in Storyboard, the tableView will still need to look for this delegate to set the height, otherwise it will use the default size. This is weird behaviour I know. It could probably be a bug, or a feature I am not sure. :D So lets add code to return the cell height.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
 return 120.0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Next, we need to tell the TableView how much data we are going to display. As you have added 8 objects to menuArray, we therefore can return this number to the numberOfRowsInSection delegate. How to do it? Simple, just use the count method of the array.&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    return [_menuArray count];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
Important: You should NEVER do calculations in this method. Because it can cause crashes in your app especially when the content of the array you use in cellForRow method does not match with the number you return here. If you want to filter the array, do it outside of delegate functions, load the filtered objects into another array, and return that array's count instead.&lt;/blockquote&gt;
&lt;br /&gt;
And finally, assigning our MODEL to CONTROLLER is using cellForRow method (read the comments to understand what each line does):&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // we need to return a cell type to this method, so start with creating our custom cell with the cell identifier we specified earlier
    MenuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"menuCellID"];
    
    // we also check if the cell is suddenly nil, and we recreate it
    if (cell==nil) {
        cell = [[MenuTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"menuCellID"];
    }
    
    // and here is where the updating according to our model occurs
    // first we get the object of the cell we're in (by using indexPath.row property)
    MenuItem *eachItem = [_menuArray objectAtIndex:indexPath.row];
    
    // then assign the values and data
    cell.menuImg.image = [UIImage imageNamed:eachItem.menuImgName];
    cell.menuPrice.text = eachItem.menuPrice;
    cell.menuName.text = eachItem.menuName;
    
    // as for chef recommended icon, we need a little conditioning
    if (eachItem.menuCode==2) {
        cell.menuIcon.image = [UIImage imageNamed:@"chef.png"];
    } else {
        cell.menuIcon.image = nil; // clear the icon 
    }
    
    // finally we return the updated cell to controller
    return cell;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
And when you run the app, you will see it works flawlessly! And that's how you use any Reusables. For your own benefit, you can try to apply the same steps to UICollectionView. Try it!&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://www.dropbox.com/s/8mqtxc5su282roi/Reusables.zip?dl=0"&gt;&lt;img border="0" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJxG0OiR4I5cgBN5SVtYoQvK4JjHyT-EsRjiDs6Mu8MH_mPgcSoDbpQmPK6jn8bpdTw9vdrj_QZ24_lqOwr8DvRqS-s7KRYw1egiWp1QcukVoy7tu3bEdU1myqnW_nrXXm7gdhunCWdy8/s320/download.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
That's all folks! Any questions? Shoot in the comment section. I may be late to reply tho but I'll reply when I can!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://xcodenoobies.blogspot.com/2017/11/how-to-create-reusable-views-with.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi62mCKS6R05jQYEwXiymomEYLq31h4f95P8F1D-drdV7Nwb4ZFyggxfq1FVKGf1gX-hSbnklSNvYFiXRmemmJbCZhTXY6DwBvnwEXM_StnhWFhvKB7WyRA31PmrMi2xY6ay2KvRD9-fD4/s72-c/download.jpg" width="72"/><thr:total>0</thr:total><enclosure length="-1" type="application/json" url="https://www.dropbox.com/s/8mqtxc5su282roi/Reusables.zip?dl=0"/><itunes:explicit/><itunes:subtitle>First, some short intro! :D My blog views has finally reached ONE MILLION!!! Now if I get a dollar for a view. Phew! None the less, I am so happy with this view count- why? Because it means I helped quite many developers to create their apps (hopefully). And those apps will benefit mankind. Even if it's a fart app, hey, it cheers up people and that is good. As noobs we tend to not getting the whole picture of a particular UI object. A label is simple, there is text property, you set it directly in Storyboard or programatically (label.text = @"hello";)&amp;nbsp;and it shows immediately. Pretty straight forward. But for objects that uses Reusable Cells like TableView, there are multiple set ups that we need to do to use it properly and therefore prevent any weird and unwanted bugs and crashes. Anyway here's what we're gonna end up with at the end of the tutorial: It's a 2.4MB GIF. What does Reusable Views mean?&amp;nbsp; It is basically a concept/method to display big amount of data in a scrollable area. In case of TableView, &amp;nbsp;the amount of cells being created by TableView is only a small quantity that is enough to fit the visible area of TableView. For example, if you have TableView of height 300, and each cells height is 10, then at least 31 cells are created at runtime. And when you scroll down the table, the cell that is being pushed out of view at the top is moved to the bottom and its content is updated according to the datasource (code in cellForRow delegate). This is how Reusable Views work. And it is same thing with CollectionView or other objects or custom libraries with Reusable things. So no matter how much data you have, the amount of cells that exist in memory is only 31, at least. Now that you understand this concept, you can code more efficiently and be able to code safely around it. Before we start to write code for our TableView example, we need to understand another concept that is MVC which means Model-View-Controller. We need to write code that comply with this concept and to do this we have to keep things separate. The MVC Concept In case of TableView, our Model is our dataSource. Our View is the TableView object in storyboard obviously. And our Controller is all the delegates functions. Our job is to create our Model that complies to our intention of the View behaviour, and connect Model and View with Controller. In normal English, we need to create our datasource (ie NSArray/NSMutableArray) that has all the necessary properties of the things in our cell and pass it to our delegates. Lets Do It Lets make a tableview that lists down a menu for a restaurant with details of the dish in each rows. Such UI is typical in many applications. How do we go about in designing this feature? We need to create a custom object to work with. Our datasource will be an array containing these objects. So we need to decide what is the contents of our cell item. You can use dictionaries but trust me, objects is the way to go. Objects make coding a lot simpler and cleaner. So I will split the process into the corresponding "section" of the design pattern: a) MODEL b) VIEW c) CONTROLLER But we'll start with VIEW first, since it's more fun. :P Setting Up The "VIEW" First, drag and drop a UITableView on your empty ViewController. Set the constraints. I leave it up to you how big you want the tableview to be. For me, I just size it up to fill the entire view. And then I drag the UITableViewCell object into the tableview. You should have something like the following. &amp;nbsp;Lets review our plan for the tableview cell (which is empty now): Menu photo - (a UIImageView) Menu name - (a UILabel) Price - (another UILabel) An icon if it is chef recommendation or not. (a UIImageView) So lets add these items to our empty cell. I made the cell bigger by dragging the bottom edge of the cell downwards. Then adding all the items and arrange them as needed and set the corresponding constraints. I also changed the cell background color just for fun. Here's what I ended up with: Next, we need to link the cell to our viewController. If your table contents are simple, like a single text for each cell, you do not need to customize the cell class and you can skip the next step and just use the default cell style class like Basic, Left Detail, Right Detail or Subtitle.&amp;nbsp; To customize cell class, right click on your Project Navigator and select New File... then specify the creation of a custom UITableViewCell as shown in image below. I named this custom class MenuTableViewCell: Now goto Storyboard and click on the tableview cell, and in the Identity Inspector, in Class textfield, key in the name of your custom cell class that you created above. In this case, MenuTableViewCell. This is a crucial step and if you miss it (many noobs do miss it, including me :D), you won't be able to connect the IBOutlet to the class header. And then, connect all the objects in your cell to the class header. Give it meaningful names. Here is the completed header of the cell class: // // MenuTableViewCell.h // Reusables // // Created by Emir Fithri on 03/11/2017. // Copyright © 2017 geneCode. All rights reserved. // #import @interface MenuTableViewCell : UITableViewCell @property (weak, nonatomic) IBOutlet UIImageView *menuImg; @property (weak, nonatomic) IBOutlet UILabel *menuName; @property (weak, nonatomic) IBOutlet UIImageView *menuIcon; @property (weak, nonatomic) IBOutlet UILabel *menuPrice; @end Next, return to storyboard and click on the TableView cell and at the Attributes Inspector key in the Identifier of your custom cell. This is very important. For this example, I named it simply menuCellID. The ID is used by the TableView to distinguish if your table has multiple type of cells styles. Leave MenuTableViewCell.m as it is. At this point, your custom TableView cell is completed and this concludes setting up the "View" part! Congrats :D Setting Up The "MODEL" Our Model is a collection of Objects in NSMutableArray. You could use NSDictionary as objects to store in the array, but custom objects will make coding a whole lot easier and cleaner. Some options of our Model So lets code our custom object first. In XCode, right click the project navigator on the left and add a new class. Name it MenuItem. Add the properties according to the details that we are going to add in the cell into the header file. Then create a standard init method for the class in .m file. We will end up as below: // // MenuItem.h // Reusables // // Created by Emir Fithri on 03/11/2017. // Copyright © 2017 geneCode. All rights reserved. // #import &amp;lt;foundation.h&amp;gt; @interface MenuItem : NSObject @property (nonatomic, strong) NSString *menuImgName, *menuName, *menuPrice; @property (nonatomic, assign) int menuCode; -(id)init; @end // // MenuItem.m // Reusables // // Created by Emir Fithri on 03/11/2017. // Copyright © 2017 geneCode. All rights reserved. // #import "MenuItem.h" @implementation MenuItem -(id)init { self = [super init]; if (self) { // you can initialize your properties here if needed } return self; } @end Now to complete setting up our "Model", we need to declare our NSMutableArray to hold the menu objects, in the viewcontroller's header file: @property (nonatomic, strong) NSMutableArray *menuArray; Finally lets create the menu objects and fill them into the menuArray. We can do this in viewDidLoad. Remember to #import "MenuItem.h" in the viewController's header so we can use the class. -(void)viewDidLoad { [super viewDidLoad]; MenuItem *menu1 = [[MenuItem alloc] init]; menu1.menuName= @"Fish &amp;amp; Chips"; menu1.menuImgName = @"menu1.jpg"; menu1.menuPrice = @"12.99"; menu1.menuCode = 1; MenuItem *menu2 = [[MenuItem alloc] init]; menu2.menuName= @"Hamburger"; menu2.menuImgName = @"menu2.jpg"; menu2.menuPrice = @"8.99"; menu2.menuCode = 1; MenuItem *menu3 = [[MenuItem alloc] init]; menu3.menuName= @"Beef Steak"; menu3.menuImgName = @"menu3.jpg"; menu3.menuPrice = @"21.59"; menu3.menuCode = 2; MenuItem *menu4 = [[MenuItem alloc] init]; menu4.menuName= @"Cappucino"; menu4.menuImgName = @"menu4.jpg"; menu4.menuPrice = @"1.99"; menu4.menuCode = 1; MenuItem *menu5 = [[MenuItem alloc] init]; menu5.menuName= @"Banana Split"; menu5.menuImgName = @"menu5.jpg"; menu5.menuPrice = @"11.29"; menu5.menuCode = 1; MenuItem *menu6 = [[MenuItem alloc] init]; menu6.menuName= @"Hot Dog"; menu6.menuImgName = @"menu6.jpg"; menu6.menuPrice = @"4.59"; menu6.menuCode = 2; MenuItem *menu7 = [[MenuItem alloc] init]; menu7.menuName= @"Grilled Chicken"; menu7.menuImgName = @"menu7.jpg"; menu7.menuPrice = @"25.59"; menu7.menuCode = 1; MenuItem *menu8 = [[MenuItem alloc] init]; menu8.menuName= @"Ice Lemon Tea"; menu8.menuImgName = @"menu8.jpg"; menu8.menuPrice = @"1.59"; menu8.menuCode = 1; //initialize our array _menuArray = [[NSMutableArray alloc] init]; [_menuArray addObject:menu1]; [_menuArray addObject:menu2]; [_menuArray addObject:menu3]; [_menuArray addObject:menu4]; [_menuArray addObject:menu5]; [_menuArray addObject:menu6]; [_menuArray addObject:menu7]; [_menuArray addObject:menu8]; } In this example, I added only 8 menu items. If you're feeling adventurous, you can go ahead and add as much items as you want. And the code I use is to make you easily understand the process so they are not simplified and not factored in anyway. You can simplify the code for menu item creation by creating your own class method in MenuItem.m, so you can simply call [_menuArray addObject:[MenuItem createWithName:@"Beef Steak" photo:@"menu1.jpg" price:@"21.59" code:2]]; I already covered about class methods and functions in previous tutorial: Basic of XCode Methods &amp;amp; Functions in Objective C. Do read it if you want to know more. And finally, of course, we have to add all our actual data (menu images, and icons). You can add them in the Asset folder. With that, we have completed setting up the "MODEL" part. Setting Up The "CONTROLLER" Now here is where the functionality comes in. A Controller for any reusable views basically consists of delegates functions and dataSource link. Some developer or tutorials refers this to "Protocol". It means the same thing. Although, if we want to be concise, we can say that UITableView implements the Protocol, and our class that uses the UITableView's protocol, implements its delegates. You can open up a UITableView.h and see it for yourself: This is how a class implements a protocol for other class to adopt and use. Get it? As you probably have noticed, we have not connected our TableView to any IBOutlet yet. Now is the time to do so. And not only that you also have to connect other things on the TableView: In total we need to hook up 3 things: i) IBOutlet ii) Datasource iii) Delegate The above picture shows how to connect the dataSource of the TableView to the ViewController. Repeat this process for "delegate" underneath it. Then connect the TableView's IBOutlet (New Referencing Outlet) to the ViewController's header. This basically tells the iOS where it can find the delegate functions and the data for this tableView (which is in ViewController). Next, open up the ViewController's header file and "implement the tableview delegate and datasource".&amp;nbsp; Basically now we need to add Delegate and Datasource in our class because that's what our UI is looking for when we run the app. To do this, just add &amp;lt;UITableViewDelegate, UITableViewDataSource&amp;gt; in the header file. Your header will now look like this: // // ViewController.h // Reusables // // Created by Emir Fithri on 03/11/2017. // Copyright © 2017 geneCode. All rights reserved. // #import &amp;lt;UIKit.h&amp;gt; #import "MenuItem.h" @interface ViewController : UIViewController &amp;lt;UITableViewDelegate, UITableViewDataSource&amp;gt; @property (nonatomic, strong) NSMutableArray *menuArray; @property (weak, nonatomic) IBOutlet UITableView *menuTable; @end Next goto the ViewController.m file and you can now enter the delegate functions of TableView. You can start to type -(void)table... and you will see code completion pops up a list of all the relevant delegate functions that you can use for the TableView. (If you don't, try hitting ESC button at the end of your typing.) And that is just a list of delegates that of the type "void". There are delegates of other types too, like NSInteger, CGFloat, and so on. Good news is, you DO NOT HAVE to implement all of these delegate function to make our table work! I'd say the minimum is 3 delegate functions: // TableView Delegates -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { } -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { } The first delegate is to set our cell height. Eventhough we have manually changed the cell size in Storyboard, the tableView will still need to look for this delegate to set the height, otherwise it will use the default size. This is weird behaviour I know. It could probably be a bug, or a feature I am not sure. :D So lets add code to return the cell height. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 120.0; } Next, we need to tell the TableView how much data we are going to display. As you have added 8 objects to menuArray, we therefore can return this number to the numberOfRowsInSection delegate. How to do it? Simple, just use the count method of the array. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [_menuArray count]; } Important: You should NEVER do calculations in this method. Because it can cause crashes in your app especially when the content of the array you use in cellForRow method does not match with the number you return here. If you want to filter the array, do it outside of delegate functions, load the filtered objects into another array, and return that array's count instead. And finally, assigning our MODEL to CONTROLLER is using cellForRow method (read the comments to understand what each line does): -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // we need to return a cell type to this method, so start with creating our custom cell with the cell identifier we specified earlier MenuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"menuCellID"]; // we also check if the cell is suddenly nil, and we recreate it if (cell==nil) { cell = [[MenuTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"menuCellID"]; } // and here is where the updating according to our model occurs // first we get the object of the cell we're in (by using indexPath.row property) MenuItem *eachItem = [_menuArray objectAtIndex:indexPath.row]; // then assign the values and data cell.menuImg.image = [UIImage imageNamed:eachItem.menuImgName]; cell.menuPrice.text = eachItem.menuPrice; cell.menuName.text = eachItem.menuName; // as for chef recommended icon, we need a little conditioning if (eachItem.menuCode==2) { cell.menuIcon.image = [UIImage imageNamed:@"chef.png"]; } else { cell.menuIcon.image = nil; // clear the icon } // finally we return the updated cell to controller return cell; } And when you run the app, you will see it works flawlessly! And that's how you use any Reusables. For your own benefit, you can try to apply the same steps to UICollectionView. Try it! That's all folks! Any questions? Shoot in the comment section. I may be late to reply tho but I'll reply when I can!</itunes:subtitle><itunes:author>noreply@blogger.com (GeneCode)</itunes:author><itunes:summary>First, some short intro! :D My blog views has finally reached ONE MILLION!!! Now if I get a dollar for a view. Phew! None the less, I am so happy with this view count- why? Because it means I helped quite many developers to create their apps (hopefully). And those apps will benefit mankind. Even if it's a fart app, hey, it cheers up people and that is good. As noobs we tend to not getting the whole picture of a particular UI object. A label is simple, there is text property, you set it directly in Storyboard or programatically (label.text = @"hello";)&amp;nbsp;and it shows immediately. Pretty straight forward. But for objects that uses Reusable Cells like TableView, there are multiple set ups that we need to do to use it properly and therefore prevent any weird and unwanted bugs and crashes. Anyway here's what we're gonna end up with at the end of the tutorial: It's a 2.4MB GIF. What does Reusable Views mean?&amp;nbsp; It is basically a concept/method to display big amount of data in a scrollable area. In case of TableView, &amp;nbsp;the amount of cells being created by TableView is only a small quantity that is enough to fit the visible area of TableView. For example, if you have TableView of height 300, and each cells height is 10, then at least 31 cells are created at runtime. And when you scroll down the table, the cell that is being pushed out of view at the top is moved to the bottom and its content is updated according to the datasource (code in cellForRow delegate). This is how Reusable Views work. And it is same thing with CollectionView or other objects or custom libraries with Reusable things. So no matter how much data you have, the amount of cells that exist in memory is only 31, at least. Now that you understand this concept, you can code more efficiently and be able to code safely around it. Before we start to write code for our TableView example, we need to understand another concept that is MVC which means Model-View-Controller. We need to write code that comply with this concept and to do this we have to keep things separate. The MVC Concept In case of TableView, our Model is our dataSource. Our View is the TableView object in storyboard obviously. And our Controller is all the delegates functions. Our job is to create our Model that complies to our intention of the View behaviour, and connect Model and View with Controller. In normal English, we need to create our datasource (ie NSArray/NSMutableArray) that has all the necessary properties of the things in our cell and pass it to our delegates. Lets Do It Lets make a tableview that lists down a menu for a restaurant with details of the dish in each rows. Such UI is typical in many applications. How do we go about in designing this feature? We need to create a custom object to work with. Our datasource will be an array containing these objects. So we need to decide what is the contents of our cell item. You can use dictionaries but trust me, objects is the way to go. Objects make coding a lot simpler and cleaner. So I will split the process into the corresponding "section" of the design pattern: a) MODEL b) VIEW c) CONTROLLER But we'll start with VIEW first, since it's more fun. :P Setting Up The "VIEW" First, drag and drop a UITableView on your empty ViewController. Set the constraints. I leave it up to you how big you want the tableview to be. For me, I just size it up to fill the entire view. And then I drag the UITableViewCell object into the tableview. You should have something like the following. &amp;nbsp;Lets review our plan for the tableview cell (which is empty now): Menu photo - (a UIImageView) Menu name - (a UILabel) Price - (another UILabel) An icon if it is chef recommendation or not. (a UIImageView) So lets add these items to our empty cell. I made the cell bigger by dragging the bottom edge of the cell downwards. Then adding all the items and arrange them as needed and set the corresponding constraints. I also changed the cell background color just for fun. Here's what I ended up with: Next, we need to link the cell to our viewController. If your table contents are simple, like a single text for each cell, you do not need to customize the cell class and you can skip the next step and just use the default cell style class like Basic, Left Detail, Right Detail or Subtitle.&amp;nbsp; To customize cell class, right click on your Project Navigator and select New File... then specify the creation of a custom UITableViewCell as shown in image below. I named this custom class MenuTableViewCell: Now goto Storyboard and click on the tableview cell, and in the Identity Inspector, in Class textfield, key in the name of your custom cell class that you created above. In this case, MenuTableViewCell. This is a crucial step and if you miss it (many noobs do miss it, including me :D), you won't be able to connect the IBOutlet to the class header. And then, connect all the objects in your cell to the class header. Give it meaningful names. Here is the completed header of the cell class: // // MenuTableViewCell.h // Reusables // // Created by Emir Fithri on 03/11/2017. // Copyright © 2017 geneCode. All rights reserved. // #import @interface MenuTableViewCell : UITableViewCell @property (weak, nonatomic) IBOutlet UIImageView *menuImg; @property (weak, nonatomic) IBOutlet UILabel *menuName; @property (weak, nonatomic) IBOutlet UIImageView *menuIcon; @property (weak, nonatomic) IBOutlet UILabel *menuPrice; @end Next, return to storyboard and click on the TableView cell and at the Attributes Inspector key in the Identifier of your custom cell. This is very important. For this example, I named it simply menuCellID. The ID is used by the TableView to distinguish if your table has multiple type of cells styles. Leave MenuTableViewCell.m as it is. At this point, your custom TableView cell is completed and this concludes setting up the "View" part! Congrats :D Setting Up The "MODEL" Our Model is a collection of Objects in NSMutableArray. You could use NSDictionary as objects to store in the array, but custom objects will make coding a whole lot easier and cleaner. Some options of our Model So lets code our custom object first. In XCode, right click the project navigator on the left and add a new class. Name it MenuItem. Add the properties according to the details that we are going to add in the cell into the header file. Then create a standard init method for the class in .m file. We will end up as below: // // MenuItem.h // Reusables // // Created by Emir Fithri on 03/11/2017. // Copyright © 2017 geneCode. All rights reserved. // #import &amp;lt;foundation.h&amp;gt; @interface MenuItem : NSObject @property (nonatomic, strong) NSString *menuImgName, *menuName, *menuPrice; @property (nonatomic, assign) int menuCode; -(id)init; @end // // MenuItem.m // Reusables // // Created by Emir Fithri on 03/11/2017. // Copyright © 2017 geneCode. All rights reserved. // #import "MenuItem.h" @implementation MenuItem -(id)init { self = [super init]; if (self) { // you can initialize your properties here if needed } return self; } @end Now to complete setting up our "Model", we need to declare our NSMutableArray to hold the menu objects, in the viewcontroller's header file: @property (nonatomic, strong) NSMutableArray *menuArray; Finally lets create the menu objects and fill them into the menuArray. We can do this in viewDidLoad. Remember to #import "MenuItem.h" in the viewController's header so we can use the class. -(void)viewDidLoad { [super viewDidLoad]; MenuItem *menu1 = [[MenuItem alloc] init]; menu1.menuName= @"Fish &amp;amp; Chips"; menu1.menuImgName = @"menu1.jpg"; menu1.menuPrice = @"12.99"; menu1.menuCode = 1; MenuItem *menu2 = [[MenuItem alloc] init]; menu2.menuName= @"Hamburger"; menu2.menuImgName = @"menu2.jpg"; menu2.menuPrice = @"8.99"; menu2.menuCode = 1; MenuItem *menu3 = [[MenuItem alloc] init]; menu3.menuName= @"Beef Steak"; menu3.menuImgName = @"menu3.jpg"; menu3.menuPrice = @"21.59"; menu3.menuCode = 2; MenuItem *menu4 = [[MenuItem alloc] init]; menu4.menuName= @"Cappucino"; menu4.menuImgName = @"menu4.jpg"; menu4.menuPrice = @"1.99"; menu4.menuCode = 1; MenuItem *menu5 = [[MenuItem alloc] init]; menu5.menuName= @"Banana Split"; menu5.menuImgName = @"menu5.jpg"; menu5.menuPrice = @"11.29"; menu5.menuCode = 1; MenuItem *menu6 = [[MenuItem alloc] init]; menu6.menuName= @"Hot Dog"; menu6.menuImgName = @"menu6.jpg"; menu6.menuPrice = @"4.59"; menu6.menuCode = 2; MenuItem *menu7 = [[MenuItem alloc] init]; menu7.menuName= @"Grilled Chicken"; menu7.menuImgName = @"menu7.jpg"; menu7.menuPrice = @"25.59"; menu7.menuCode = 1; MenuItem *menu8 = [[MenuItem alloc] init]; menu8.menuName= @"Ice Lemon Tea"; menu8.menuImgName = @"menu8.jpg"; menu8.menuPrice = @"1.59"; menu8.menuCode = 1; //initialize our array _menuArray = [[NSMutableArray alloc] init]; [_menuArray addObject:menu1]; [_menuArray addObject:menu2]; [_menuArray addObject:menu3]; [_menuArray addObject:menu4]; [_menuArray addObject:menu5]; [_menuArray addObject:menu6]; [_menuArray addObject:menu7]; [_menuArray addObject:menu8]; } In this example, I added only 8 menu items. If you're feeling adventurous, you can go ahead and add as much items as you want. And the code I use is to make you easily understand the process so they are not simplified and not factored in anyway. You can simplify the code for menu item creation by creating your own class method in MenuItem.m, so you can simply call [_menuArray addObject:[MenuItem createWithName:@"Beef Steak" photo:@"menu1.jpg" price:@"21.59" code:2]]; I already covered about class methods and functions in previous tutorial: Basic of XCode Methods &amp;amp; Functions in Objective C. Do read it if you want to know more. And finally, of course, we have to add all our actual data (menu images, and icons). You can add them in the Asset folder. With that, we have completed setting up the "MODEL" part. Setting Up The "CONTROLLER" Now here is where the functionality comes in. A Controller for any reusable views basically consists of delegates functions and dataSource link. Some developer or tutorials refers this to "Protocol". It means the same thing. Although, if we want to be concise, we can say that UITableView implements the Protocol, and our class that uses the UITableView's protocol, implements its delegates. You can open up a UITableView.h and see it for yourself: This is how a class implements a protocol for other class to adopt and use. Get it? As you probably have noticed, we have not connected our TableView to any IBOutlet yet. Now is the time to do so. And not only that you also have to connect other things on the TableView: In total we need to hook up 3 things: i) IBOutlet ii) Datasource iii) Delegate The above picture shows how to connect the dataSource of the TableView to the ViewController. Repeat this process for "delegate" underneath it. Then connect the TableView's IBOutlet (New Referencing Outlet) to the ViewController's header. This basically tells the iOS where it can find the delegate functions and the data for this tableView (which is in ViewController). Next, open up the ViewController's header file and "implement the tableview delegate and datasource".&amp;nbsp; Basically now we need to add Delegate and Datasource in our class because that's what our UI is looking for when we run the app. To do this, just add &amp;lt;UITableViewDelegate, UITableViewDataSource&amp;gt; in the header file. Your header will now look like this: // // ViewController.h // Reusables // // Created by Emir Fithri on 03/11/2017. // Copyright © 2017 geneCode. All rights reserved. // #import &amp;lt;UIKit.h&amp;gt; #import "MenuItem.h" @interface ViewController : UIViewController &amp;lt;UITableViewDelegate, UITableViewDataSource&amp;gt; @property (nonatomic, strong) NSMutableArray *menuArray; @property (weak, nonatomic) IBOutlet UITableView *menuTable; @end Next goto the ViewController.m file and you can now enter the delegate functions of TableView. You can start to type -(void)table... and you will see code completion pops up a list of all the relevant delegate functions that you can use for the TableView. (If you don't, try hitting ESC button at the end of your typing.) And that is just a list of delegates that of the type "void". There are delegates of other types too, like NSInteger, CGFloat, and so on. Good news is, you DO NOT HAVE to implement all of these delegate function to make our table work! I'd say the minimum is 3 delegate functions: // TableView Delegates -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { } -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { } The first delegate is to set our cell height. Eventhough we have manually changed the cell size in Storyboard, the tableView will still need to look for this delegate to set the height, otherwise it will use the default size. This is weird behaviour I know. It could probably be a bug, or a feature I am not sure. :D So lets add code to return the cell height. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 120.0; } Next, we need to tell the TableView how much data we are going to display. As you have added 8 objects to menuArray, we therefore can return this number to the numberOfRowsInSection delegate. How to do it? Simple, just use the count method of the array. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [_menuArray count]; } Important: You should NEVER do calculations in this method. Because it can cause crashes in your app especially when the content of the array you use in cellForRow method does not match with the number you return here. If you want to filter the array, do it outside of delegate functions, load the filtered objects into another array, and return that array's count instead. And finally, assigning our MODEL to CONTROLLER is using cellForRow method (read the comments to understand what each line does): -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // we need to return a cell type to this method, so start with creating our custom cell with the cell identifier we specified earlier MenuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"menuCellID"]; // we also check if the cell is suddenly nil, and we recreate it if (cell==nil) { cell = [[MenuTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"menuCellID"]; } // and here is where the updating according to our model occurs // first we get the object of the cell we're in (by using indexPath.row property) MenuItem *eachItem = [_menuArray objectAtIndex:indexPath.row]; // then assign the values and data cell.menuImg.image = [UIImage imageNamed:eachItem.menuImgName]; cell.menuPrice.text = eachItem.menuPrice; cell.menuName.text = eachItem.menuName; // as for chef recommended icon, we need a little conditioning if (eachItem.menuCode==2) { cell.menuIcon.image = [UIImage imageNamed:@"chef.png"]; } else { cell.menuIcon.image = nil; // clear the icon } // finally we return the updated cell to controller return cell; } And when you run the app, you will see it works flawlessly! And that's how you use any Reusables. For your own benefit, you can try to apply the same steps to UICollectionView. Try it! That's all folks! Any questions? Shoot in the comment section. I may be late to reply tho but I'll reply when I can!</itunes:summary><itunes:keywords>beginner, delegates, guide, iamja77, ios, newbie, obj-c, objective c, reusables, uicollectionview, uitableview</itunes:keywords></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-6639417407800175722</guid><pubDate>Fri, 08 Sep 2017 00:40:00 +0000</pubDate><atom:updated>2017-09-07T17:40:42.150-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">api</category><category domain="http://www.blogger.com/atom/ns#">can</category><category domain="http://www.blogger.com/atom/ns#">deprecated</category><category domain="http://www.blogger.com/atom/ns#">framework</category><category domain="http://www.blogger.com/atom/ns#">function</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">not</category><category domain="http://www.blogger.com/atom/ns#">or</category><category domain="http://www.blogger.com/atom/ns#">use</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><title>Can you use Deprecated Functions?</title><description>Hey guys, I am making a few tutorials but all are in progress right now. Hope to publish them this weekend. Anyways, as a frequent StackOverflow visitor, I often read programmers wanting to change the functions they used that are deprecated. From their postings, I get that many programmers think that deprecated means "cut off" and therefore cannot be used indefinitely. This is, false.&lt;br /&gt;
&lt;br /&gt;
Let us take a look at the meaning of the word first.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV9UmsAzB7MlJvmsPo2JfBIV3ECRTp-IaTB6dJoiB1JPneczz-0qnX8kguV5Qnx8DLhvaMuADW0tfW5Dcpe_VEtOSw-SbU7MfiunpCccMtGbHyTiNVRug5A_yb8XGHFscr2Z5DJh55-sU/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="471" data-original-width="567" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV9UmsAzB7MlJvmsPo2JfBIV3ECRTp-IaTB6dJoiB1JPneczz-0qnX8kguV5Qnx8DLhvaMuADW0tfW5Dcpe_VEtOSw-SbU7MfiunpCccMtGbHyTiNVRug5A_yb8XGHFscr2Z5DJh55-sU/s1600/Capture.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Basically, it means disapproved (or in layman terms, not advised to be used). It is not the same as totally cannot be used in which case the word is BANNED. Deprecated is not banned. It is only advisable not to use the function. BUT YOU CAN STILL USE IT.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
In iOS developer terms, you can surely use a deprecated function, but you must start thinking/planning/coding of the new function to replace it in 4-5 years time. Deprecated functions normally are supported for a long time before they are removed. This is because often, Apple creates new and better frameworks for a thing. But there will be many apps that rely on that framework that are already in the App Store. So to immediately ban a function, is an act of oppression.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
For example, NSURLConnection. It was introduced in iOS2.0. It's successor, the NSURLSession was introduced in iOS7.0. So since iOS7.0, NSURLConnection is therefore flagged as deprecated. But can you still use it in iOS10? YES IT STILL WORKS. In iOS11? Nobody knows (except the beta users right now). Given 3 versions of iOS has passed, you oughta change it by now.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
But if it was *just* deprecated in iOS9 for example, no sweat because that function will definitely be available even in iOS11. So if you're doing a quick update of your apps, very old functions that are deprecated (like the ones intro'd in iOS2.0), should be replaced. But if the deprecation appear in iOS8 or 9, you're likely safe to leave it as it is for now.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Hope this post has been beneficial. Happy coding!&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://xcodenoobies.blogspot.com/2017/09/can-you-use-deprecated-functions.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV9UmsAzB7MlJvmsPo2JfBIV3ECRTp-IaTB6dJoiB1JPneczz-0qnX8kguV5Qnx8DLhvaMuADW0tfW5Dcpe_VEtOSw-SbU7MfiunpCccMtGbHyTiNVRug5A_yb8XGHFscr2Z5DJh55-sU/s72-c/Capture.PNG" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-8835666438945527511</guid><pubDate>Sun, 09 Jul 2017 06:29:00 +0000</pubDate><atom:updated>2017-10-14T00:54:33.641-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">block</category><category domain="http://www.blogger.com/atom/ns#">completion</category><category domain="http://www.blogger.com/atom/ns#">custom</category><category domain="http://www.blogger.com/atom/ns#">example</category><category domain="http://www.blogger.com/atom/ns#">functions</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">methods</category><category domain="http://www.blogger.com/atom/ns#">objective c</category><category domain="http://www.blogger.com/atom/ns#">sample</category><category domain="http://www.blogger.com/atom/ns#">tutorial</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><title>How to: Basic of XCode Methods &amp; Functions in Objective-C</title><description>Why ObjC?&lt;br /&gt;
&lt;br /&gt;
Cause we're oldskool! :D&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdtGRZVMRVEbLXQu7aM60HwUvDGyo39wyTOVV0gImWaQQTM2-TZx3tmgE2wpHqmPqGKdiVrKdCEPNJNhvU_Ipc4HcE0aKmi0OmI1tIrmntt5ZNIsAM7BjtlhKvI0IWAKz7Onb4eDB6t0g/s1600/download.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="258" data-original-width="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdtGRZVMRVEbLXQu7aM60HwUvDGyo39wyTOVV0gImWaQQTM2-TZx3tmgE2wpHqmPqGKdiVrKdCEPNJNhvU_Ipc4HcE0aKmi0OmI1tIrmntt5ZNIsAM7BjtlhKvI0IWAKz7Onb4eDB6t0g/s1600/download.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;INTRODUCTION&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When we start to code, what we need to do is write methods on top of the already available delegates (namely the View Lifecycles delegates like &lt;b&gt;viewDidLoad&lt;/b&gt; or &lt;b&gt;viewDidLayoutSubviews&lt;/b&gt;). A typical method that we quickly create is IBActions. These are automatically created when you drag an outlet in Storyboard to your header file.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(IBAction)aButtonWasClicked:(id)sender {
&amp;nbsp; // your button was clicked by user
}&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The &lt;b&gt;aButtonWasClicked:&lt;/b&gt; is the name of the method. Note that I include the &lt;b&gt;semicolon&lt;/b&gt; at the end. This indicates there is a parameter to be supplied to the method. So if you want to call this method elsewhere programatically, you need to write:&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
[self aButtonWasClicked:obj];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
If you don't know what is obj, and sender is never used in the method, you can supply nil to it:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
[self aButtonWasClicked:nil];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
And if you want to supply it to a&amp;nbsp;@selector() you do it this way:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
@selector(aButtonWasClicked:) // semicolon is important
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
If you know what sender is (in this case, obviously a UIButton), you can make use of it by using TYPECASTING. Typecast is basically implying a certain type to a generic/unknown object. For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(IBAction)aButtonWasClicked:(id)sender {
   UIButton *button = (UIButton*)sender; // this is typecasting of the sender obj which is type "id" to "UIButton"
   // now you can use button object properties.
   [button setTitle:"I was Clicked!" forState:UIControlStateNormal];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Okay. Now on to writing your own method - &lt;b&gt;which is the cool part!&lt;/b&gt;. There are quite a few types of methods, but the most common ones are &lt;i&gt;instance&lt;/i&gt; method and &lt;i&gt;class&lt;/i&gt; method. Instance methods are the ones started with a dash "-". And class methods are the ones started with a plus "+".&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;INSTANCE METHODS&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Instance methods are called by... &lt;b&gt;drumroll&lt;/b&gt;... an instance of the object. Most instance methods are normally called by the viewController in which they contain, which is "&lt;i&gt;self&lt;/i&gt;", hence we see &lt;b&gt;[self...&lt;/b&gt; at the front.&lt;br /&gt;
&lt;br /&gt;
Instance methods are most common, and there are a few variations of it. The most common that I use is like below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(void)setColorForView:(UIColor*)color andSize:(CGSize)size {

}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Lets break this method down. "-" indicates it is an instance method. The thing in bracket is the return value of this method. void means nothing. So you will get nil returned by this method if you call it by assignment. For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
id value = [self setColorForView:clr andSize:size];

// value here will be nil always.
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Next, setColorForView: is the NAME of the method AND it also acts as a selector name for the first parameter. andSize is the selector name for the next parameter. You can add to the method as much as you want. But be practical. Such method as below is ridiculous to say the least.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(void)setColorForView:(UIColor*)color andSize:(CGSize)size andHeight:(CGFloat)height 
withFlag:(int)flag andViewController:(UIViewController*)viewCtrl 
andYourMom:(UIMom*)mom isFat:(UIFat*)fat {
 // crazy!
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
LOL!&lt;br /&gt;
&lt;br /&gt;
Then you ask, what if I want to pass many parameters into the method? Well, you can simplify it by adding your parameters into NSDictionary and simply use:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(void)setColorForView:(NSDictionary*)params {
   // get color: [params objectForKey:@"Color"];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Or, best way is to create a custom object with all the parameters and pass that instead of dictionary.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(void)setColorForView:(MyParams*)params {
&amp;nbsp;// get color: params.color;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Better and cleaner method name right?&lt;br /&gt;
&lt;br /&gt;
What if you want your method to return a value? Remember the void? Now just replace that with a type that you want to return. For example lets make the method return a Boolean:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(BOOL)setColorForView:(UIColor*)color andSize:(CGSize)size {
 if (size.width&amp;gt;100)
   return YES; 
 else 
   return NO; 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Do you want to be fancy? a simple if/else statement can be reduced to a one-liner like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(BOOL)setColorForView:(UIColor*)color andSize:(CGSize)size {
  return (size.width&amp;gt;0)?YES:NO; // woaaahh mindblown!
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The method checks for size.width if it is over 100, the method returns YES, and if not returns NO. You can use this method like below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
BOOL widthOverHundred = [self setColorForView:color andSize:size];
// widthOverHundred now will be YES or NO depending on size value.
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
You can also return an &lt;b&gt;OBJECT&lt;/b&gt; from instance method. For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(UIColor*)getColorForView:(int)tag { 
  if (tag==0) return [UIColor redColor]; 
  else return [UIColor greenColor]; 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that an Object type name includes * to indicate a pointer to the object.&lt;br /&gt;
&lt;br /&gt;
What if you want to return many values and objects??? Hopefully you've guessed it, just use NSDictionary or custom object.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(NSDictionary*)getParamsForView:(int)tag {
&amp;nbsp; &amp;nbsp; NSDictionary *dict =// construct dictionary here
&amp;nbsp; &amp;nbsp; return dict;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(MyParams*)getParamsForView:(int)tag {
&amp;nbsp; &amp;nbsp; MyParams&amp;nbsp;*params =// construct params here
&amp;nbsp; &amp;nbsp; return params;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
That's about all there is to know about instance methods, for noobs like us. Pretty easy peasy lemon squeezy.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;CLASS METHODS&lt;/b&gt;&lt;br /&gt;
Class methods are similar, but implementation is different. I seldom use it except some special cases. A real world example of Class Method is&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
[NSString stringWithFormat:@"%d",val];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
"stringWithFormat:" is the class method. As you can see, we can use it immediately using its class and there is no need for us to create an "instance" of the class before we use it.&lt;br /&gt;
&lt;br /&gt;
Typically a class method is created in custom class. Or when you create a category of an existing class.&lt;br /&gt;
&lt;br /&gt;
Consider a custom class called Vehicle.&lt;br /&gt;
&lt;br /&gt;
With class methods we can init a particular vehicle with different types and the correct seatCapacity.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(id)init {
 self = [super init];
 if (self) {
 // any default init setup
 }
 return self;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
+(id)createCar {
  Vehicle *obj = [[self alloc] init];
  obj.seatCapacity = 5.0;
  return obj;
}
 
+(id)createBus { 
  Vehicle *obj = [[self alloc] init];
  obj.seatCapacity = 20.0; 
  return obj; 
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
To use it:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
Vehicle *car = [Vehicle createCar];
Vehicle *bus = [Vehicle createBus];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Pretty cool eh?&lt;br /&gt;
&lt;br /&gt;
Another useful type of Class method is the completion block (which I love very much). It is exactly like having an office boy who does errands for you XD and returns to you when the job is done. Completion block is extremely useful when you want to execute something that takes time, for example, downloading or uploading data. For example, here's a class completion block method to download an image file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
+(void)downloadImageWithURL:(NSString *)urlString
          completedWithData:(void(^)(NSData *data))completedWithData
                    failure:(void(^)(NSString *errorMessage))failure

{
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSMutableCharacterSet *chars = NSCharacterSet.URLQueryAllowedCharacterSet.mutableCopy;
    NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEncodingWithAllowedCharacters:chars]];
    NSURLSessionDataTask *task = [session dataTaskWithURL:url
                                completionHandler:^(NSData *data,
                                                    NSURLResponse *response,
                                                    NSError *error) {
                                    
                                    if ((error==NULL)&amp;amp;&amp;amp;([data length]&amp;gt;0)) {
                                        
                                        completedWithData(data);
                                        
                                    } else {
                                        
                                        failure(@"NO_DATA");
                                        
                                    }
                                    
                                }];
    [task resume];

}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Put this in your custom class, say, "DownloadManager", then in your ViewController.h import DownloadManager.h and then you can you it in your ViewController.m like so:&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
[DownloadManager downloadImageWithURL:@"https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg" completedWithData:^(NSData *data) {
        
        dispatch_async(dispatch_get_main_queue(), ^{
            self.myImage.image = [UIImage imageWithData:data];
        });
        
    }failure:^(NSString *errorMsg) {
        NSLog(@"ERROR: %@",errorMsg);
        
    }];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
This is particularly useful when you want to have an asynchronous image downloader to be used with your TableView or CollectionView.
Sure, the class method is not complete, for example, you should also add a way to save the downloaded images into a "cache" of some sort if you
are using it with TableView/CollectionView. But here, I just want to demonstrate the Class block method.

&lt;br /&gt;
&lt;br /&gt;
So that's all there is to it as a basic introduction to Objective-C methods for iOS. I'll add more if I remember anything that I missed out. Meanwhile, comment below if you have any opinions. Thank you for reading!</description><link>http://xcodenoobies.blogspot.com/2017/07/how-to-basic-of-xcode-methods-functions.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdtGRZVMRVEbLXQu7aM60HwUvDGyo39wyTOVV0gImWaQQTM2-TZx3tmgE2wpHqmPqGKdiVrKdCEPNJNhvU_Ipc4HcE0aKmi0OmI1tIrmntt5ZNIsAM7BjtlhKvI0IWAKz7Onb4eDB6t0g/s72-c/download.jpg" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-8331625044659853102</guid><pubDate>Sat, 29 Apr 2017 04:36:00 +0000</pubDate><atom:updated>2019-04-20T22:24:08.520-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">app</category><category domain="http://www.blogger.com/atom/ns#">approach</category><category domain="http://www.blogger.com/atom/ns#">considerations</category><category domain="http://www.blogger.com/atom/ns#">design</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">planning</category><category domain="http://www.blogger.com/atom/ns#">wireframe</category><category domain="http://www.blogger.com/atom/ns#">wireframing</category><title>How To: Seriously Plan and Design an iOS Apps or Games</title><description>Hey whatsapp? (see what I did there? XD)&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
All these while we've been playing with XCode and making fun things without much care of how our app's structure looks like.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglUd1f_Iy07W131gGDUQcXR-EE7_PoOp2Mo7QwMpZcHklpKYrQwfocitcNV8ugbewQbdzCcJKep9r6SU68HQhM4Wh-_ZPg0xn4KNRzYi_Ad260TwoIKzBED8PTUNuepP58GRJ1VXDkK44/s1600/Wireframes2-02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglUd1f_Iy07W131gGDUQcXR-EE7_PoOp2Mo7QwMpZcHklpKYrQwfocitcNV8ugbewQbdzCcJKep9r6SU68HQhM4Wh-_ZPg0xn4KNRzYi_Ad260TwoIKzBED8PTUNuepP58GRJ1VXDkK44/s640/Wireframes2-02.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The thing about making an app/software, there are so many ways to do one thing. So many ways to code a feature. But if you are serious in making apps, you need to consider your app carefully and thoroughly, so that updating the app won't be a pain in the a$$ in the future. This is more so, when making your own app, or an app for a customer that may be requested to be updated in the future. The overall structure and back bone of the app needs to be as good and as organized as possible. Otherwise you'll end up crazy, trying to make sense of things in the app or when you want to add a new feature to the app.&lt;br /&gt;
&lt;br /&gt;
So what you should do? I now will outline the necessary steps and points for you to consider when making an app.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
1. APP WIREFRAME (UI PART)&lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
This is perhaps the first most important part of designing an app. Wireframing is basically a sketch of how an app/game going to look like and how it will work. Page per page. It is best to go as detail as possible. For example, how many views it will have, and how does each view interact with each other. And also, what kind of animations, menus, confirmation dialogs, to have. What's important to note when designing the wireframe, you need to consider any views that can be REUSED, and those should be created once and the small variations therein be controlled by a property in that view. This is to prevent having multiple views that are very similar, and having similar codes in both views. It doubles or triple your job really - when you update on one view, you also need to do the same on another view. This is bad for you! Programmers must be lazy, and so he must create views as efficient as he can.&lt;br /&gt;
&lt;br /&gt;
Anyway, here is an example of a wireframe of my app Blur.Depth that I made with an A4 paper.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiayxiu44XSlgHj9b2QYs9-_8zqbfhRKLmjPYp9d7iDzh3nmNz1_VhZ8oGKiDXEfuTvs1CdR3MsHBda3AWW51xUEE7pxUmCrm2Yd_JQYLb-BfcOU5Iw5jrp4Eoqu7lTa_njzr6jSPArbvQ/s1600/Photo+29-04-2017%252C+11+15+56+AM.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiayxiu44XSlgHj9b2QYs9-_8zqbfhRKLmjPYp9d7iDzh3nmNz1_VhZ8oGKiDXEfuTvs1CdR3MsHBda3AWW51xUEE7pxUmCrm2Yd_JQYLb-BfcOU5Iw5jrp4Eoqu7lTa_njzr6jSPArbvQ/s320/Photo+29-04-2017%252C+11+15+56+AM.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
There are plenty aspects of wireframing. For example position of buttons, controls, labels, are all important. You need to imagine a user using your app when you design it. Tab bars and toolbars normally are located at the bottom. This is because it is closest to user's thumb when a person uses a smartphone. It is safe to assume everyone is right handed (XD), so design your controls with that in mind. See the area where the thumb can reach.The top bar can also have controls, but should be minimized and not a control that user going to be using frequently.&lt;br /&gt;
&lt;br /&gt;
In addition to the wireframing, you need to choose COLORS! Yes, colors play important role in your app. Normally you could choose a theme color. A color is important for people to recognize your app by. A clear example of this is Twitter and Facebook. Yes they both already chose and sticking with their color theme. Twitter a light blue. And Facebook a dark blue. It is not a must though. Some apps don't even have a theme color. But they use a certain shade of any color and it can work nicely. See below:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwM83qFQwTB8DiaOnv_L_6Nge1GhHg78hLT7SjFSkuWXSKaV_x483UavsjSYnIg2b1-cC1MUqPGt48YkCTK-ddFB4oo8KOT8iOPpb1AF2og8RFlFT2lgX-saanhWo0PZRb6YSyD0ZYxw0/s1600/Abracadabra-App-by-Sergey-Valiukh.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwM83qFQwTB8DiaOnv_L_6Nge1GhHg78hLT7SjFSkuWXSKaV_x483UavsjSYnIg2b1-cC1MUqPGt48YkCTK-ddFB4oo8KOT8iOPpb1AF2og8RFlFT2lgX-saanhWo0PZRb6YSyD0ZYxw0/s320/Abracadabra-App-by-Sergey-Valiukh.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
This is where your art skill going to shine. If you don't know art, you can learn like how I did. I chose Inkscape and learn how to create shapes and then made all my app's graphics assets. If not, you need to hire a graphics designer to do this for you.&lt;br /&gt;
&lt;br /&gt;
To add, there are multiple tools out there to do wireframing. Even lets you run the prototype in your device. That way you can experience how your app is going to feel before actually start designing it. It is always good to have that chance. Decisions made at this time is crucial to how the app going to look and feel like at the end.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
2. LANGUAGE CHOICES&lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Before you start to create a project, you need to decide which language you are going to code the app with. As of right now, &lt;b&gt;Swift&lt;/b&gt; should be your choice. I started with &lt;b&gt;Objective-C &lt;/b&gt;and are now well versed in it in my own style of coding, so I haven't made a single app on Swift (XD Im sure ill regret it later). And also choose if you are going to use XCode (Apple's official app IDE) or others (Xamarin, PhoneGap, etc). Xamarin uses &lt;b&gt;C#&lt;/b&gt; (C-Sharp). Some even uses &lt;b&gt;HTML/XML&lt;/b&gt;. AND, there are also app maker that don't even require you to code at all (but pretty limited what they can do). For me I always prefer native, but if you want to develop once for multi platform, then you can consider others. Game is much easier to make multiplatform than apps because game doesn't normally need platform specific controls. Once you decide that, then you can start creating a project.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
3. SOURCE CONTROL OR NOT&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Before I work with a company as an app developer, I never used source control. As such my source codes are stored locally in my machine. (Not smart, actually very dumb really). I make a backup copy once in a while into my iCloud. But many times I have experienced where I changed the code too much over a day and not happy with its direction. There is no way to undo this (Ctrl-Z dont work because I have saved it and close the project during lunch). The copy in the iCloud's progress was too far away back. Had no choice but to undo manually. So many times wasted there!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Source control deals with these kinds of issue superbly. The only problem is that for source control service to be private, &lt;i&gt;you need to pay for it&lt;/i&gt;. Free ones like &lt;b&gt;github or bitbucket&lt;/b&gt;, exposes your sources to all, but I'm not really sure I might be wrong. I haven't searched for a free private source control hub, but if you find any, feel free to share in the comment section. Or if you have your own server, you could setup a free source control service hub on your own server.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Source control is also great when you have multiple people working on the same project (but &amp;nbsp;of different modules - &lt;b&gt;because having multiple people working on same module will give you merging headaches&lt;/b&gt;). If you don't understand what Source Control is, in simple terms&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
Source Control is basically a multiple copies of your project stored at different times. Basically everytime you "commit" a project, a copy of it is added to the server together with a date-timestamp. And you can move between each commits by just double clicking the commits in its timeline and instantly your project in your machine will be updated to those copies. You can also have "branches" where a project splits into two (or more) so each branch is handled by a single developer working on different module of the app. These "branches" then can be merged upon completion.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;br /&gt;
There are free software to handle source sontrol such as &lt;a href="https://www.sourcetreeapp.com/"&gt;SourceTree&lt;/a&gt;, or even GitHub has its own software too.&lt;br /&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;
4. COCOAPODS OR NOT&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I find that using &lt;b&gt;CocoaPods&lt;/b&gt; is always best if you use native solution. Even when you don't use any library that they offer, it readies the app for future library usage. There are plenty of cool libraries in cocoaPods! For me, at most I use the admob cocoapods, because most of other objects I normally create myself (subclassing). But still it is nice to have a centralized location of library you use, so that you don't have to keep on downloading it when a new version is released. And some of the library you simply almost need to use an opensource one that are well made and used by many, for example the websocket library, SocketRocket.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;
5. STORYBOARDS OR NOT&lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
If you decide on XCode, then you SHOULD REALLY use Storyboards! I know, I was a stubborn noob back then, sticking to xibs. But storyboards make your navigation between views much easier. So so much easier. And whether you use storyboards or not, you should also use AutoLayout with constraints. Constraints may look hard at first but it is actually very easy once you understand the concept. It is also much superior than the old ResizingMask.&lt;/div&gt;
&lt;div&gt;
&lt;h3&gt;
&lt;br /&gt;6. CODING DECISIONS&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Now comes the personal part. Coding decisions and styles.&lt;br /&gt;
&lt;br /&gt;
You surely have your own styles, but to me it is important to &lt;b&gt;ORGANIZE&lt;/b&gt; and always &lt;b&gt;REFACTOR&lt;/b&gt; anywhere you can. If you are working in a team, it is probably best that you assign each module to a single developer, and only he will touch those modules. Anyway here is how my style of coding is:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A. I must have an AppConstants.h header in the app.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
All the constants should be &lt;i&gt;centralized&lt;/i&gt; here. Don't use AppDelegate or any of your singletons to store the constants. Among the constants that I store normally are color themes, server URL, and any static strings that I use like Error messages, dictionary keys, userdefaults keys, segueIdentifiers and so on. There shouldn't be any hardcoded values anywhere else. So when you want to change static values, you just open AppConstants.h and it's all there, and you change once and effective everywhere! Makes your job easy and not messy.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;B. I have a common methods class.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I also have a common methods class, where any methods that are going to be used (or foreseen to be used) by many viewcontrollers are written. Examples of such methods are:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;-function to make a view (or any of its subclasses) rounded. (layer.cornerRadius).&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;-check internet connections&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;-resize a UIImage&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;-QRCode generator&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;-save an image to documents folder (both png or jpg).&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;-save an image to tmp folder (png or jpg)&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;-load an image from documents folder&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;-load an image from tmp folder&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;-etc&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;C. I use delegates and avoid overusing the NSNotificationCenter and UserDefaults.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Delegates are a great way to interacting between two or more viewcontrollers. I just learnt about delegates last year (2016) and I am wondering why didn't I learn about this sooner. NSNotifications, while it works, it doesn't have a destination. It's like a guy shouting on a mountain, hoping someone in the town nearby hears it. Some people use userdefaults to keep on writing/reading data between viewcontrollers. This works, too, but... reading and writing causes extra battery usage. You want to make people use least power when they're using your app. And.... I know many devs will cry "Singletons are bad and evil", but for me Singleton is the best ever thing I learnt in programming. And let me quote a cocos2dx developer:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
I use a single singleton, and frankly ignore the 'singletons are bad' cry-babies.&lt;/blockquote&gt;
&lt;br /&gt;
&lt;b&gt;D. I try to keep with the MVC pattern.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Back in the early days, I don't really understand MVC. Probably still don't. But the idea of MVC that I get now make sense. You have to separate codes within their confinement. A model code should remain in model, the view code remain in view, and controller code remain in controller. A good example of this is when creating a UITableView. Your views, of course are the storyboard. The model is the datasource of the table, normally a NSArray or NSMutableArray. The controller is the tableview delegates. To make this follow MVC, you don't define the model in cellForRow (while that can work). What you do is define the model outside of the delegate (ie, you setup the data in viewDidload or other place), then you code the controller (cellForRow) to read the model only. This way, each MVC stays in their boundaries.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;E. I organize my Project Navigator and arrange Storyboards nicely.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In the left panel of XCode there is a Project Navigator. It helps me to organize this. I create folders for each scenes. If you use libraries, then have a folder called "Library" and drag all of them there. Don't leave them all over the places. Organized Project Navigator allows me to find a class easily and quickly.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;F. I use Meaningful Names !!!&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Name everything meaningfully. Early this year I went to an iOS app developer interview just to see how valuable my app developing experience is. The company owner himself interviewed me. After completing a coding task, he commented quite a few things on my code and I agree with him completely. One of it was about the Project class naming. I left the default ViewController.m/h as it is... while it should've been renamed as MainViewController or something meaningful related to the Scene it represents.&lt;br /&gt;
&lt;br /&gt;
Even variable names must make sense. Having a BOOL named "&lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;yesOrNo&lt;/span&gt;" is useless to the code reader (which could be yourself in 2 years). Long variable names are okay if it is needed to explain about itself. Something like &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;_isWifiConnectionAvailable&lt;/span&gt; is totally good to me.&lt;br /&gt;
&lt;br /&gt;
And last but not least, you should also give meaningful names to your graphics assets or any other assets that you use (video, mp3, wav etc). &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;anIcon.png&lt;/span&gt; is about as descriptive as "&lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;I shit thru my a-hole&lt;/span&gt;". XD.&lt;br /&gt;
&lt;h3&gt;
&lt;br /&gt;6. FUTURE PREPARATION&lt;/h3&gt;
&lt;br /&gt;
This is also important aspect of the app planning. What would you like to do with the app in the future? Most definitely you are going to need to update it. There is not buts in this. What additional features do you have planned for version 1.1, 1.2, etc? And do you want to offer additional features or are you going to just update according to latest iOS and focus on user experience?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Many apps developers adopt the "add feature" mindset to an app updates, which I oppose full-heartedly&lt;/b&gt;. As such, a small app with &lt;i&gt;sufficient&lt;/i&gt; features, suddenly become this monster of a beast that is so ugly and it can transform to Optimus Prime and also make your coffee hahaha! &lt;i&gt;But an app or software is not supposed to do everything.&lt;/i&gt; An app or software is actually supposed to do what it is designed to do, in the most efficient, and beautiful manner, with least bugs (hey we all must admit zero bugs is impossible).&lt;br /&gt;
&lt;br /&gt;
So while developing, have in mind of the future updates you'd like to do. If you want to add features to a scene, make sure the control you choose for the scene now is able to cope with the additional feature in the future.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
7. SUMMARY&lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
After reading all the above, you should now have an idea how you should approach about making an app or game. With good planning and design and preparation, your app is going to be noticed by many people and people will love using it and don't even mind paying 99cents for it. Good luck!&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://xcodenoobies.blogspot.com/2017/04/how-to-seriously-plan-and-design-ios.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglUd1f_Iy07W131gGDUQcXR-EE7_PoOp2Mo7QwMpZcHklpKYrQwfocitcNV8ugbewQbdzCcJKep9r6SU68HQhM4Wh-_ZPg0xn4KNRzYi_Ad260TwoIKzBED8PTUNuepP58GRJ1VXDkK44/s72-c/Wireframes2-02.png" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-7961886246551016836</guid><pubDate>Sun, 26 Feb 2017 09:25:00 +0000</pubDate><atom:updated>2017-02-26T01:26:14.082-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cgcontext</category><category domain="http://www.blogger.com/atom/ns#">coregraphics</category><category domain="http://www.blogger.com/atom/ns#">paint</category><category domain="http://www.blogger.com/atom/ns#">redo</category><category domain="http://www.blogger.com/atom/ns#">undo</category><title>How To: Create Undo and Redo in a Drawing App</title><description>Hi guys.&lt;br /&gt;
&lt;br /&gt;
I want to share how to create undo and redo in a drawing app. I tried using NSUndoManager for this, but it doesn't work. Why? I don't know. When something don't work, I tried for a bit, and if I have no more idea to try and work it out, I simply abandon the idea and try something else totally. There is no point lingering on something that you simply do not know.&lt;br /&gt;
&lt;br /&gt;
The way to implement undo and redo is quite simple really. You just detect user's end stroke, and then save that drawn image into a MutableArray. This will eat memory a bit especially if you have a very big image. Alternatively you can simply store the drawn image in the TMP folder of your app sandbox use names like "undo0.png, undo1.png, undo2.png...". Have a global undo index variable to keep track of the undo/redo steps. When undoing, you -1 to the index, and load the image based on this index number. And when redoing, you&amp;nbsp;+1 to the index, and load that image.&lt;br /&gt;
&lt;br /&gt;
Something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(void)undo {
undoIndex -= 1;
NSString *imageName = [NSString stringWithFormat:@"%undold.png",undoIndex];
yourImage.image =  [self loadImageFromTMP:imageName];
}

-(void)redo {
undoIndex += 1;
NSString *imageName = [NSString stringWithFormat:@"%undold.png",undoIndex];
yourImage.image =  [self loadImageFromTMP:imageName];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Of course, you have to handle the undoIndex limits (&amp;gt;=0 and &amp;lt;maxUndolevel). Simple right? Kthxbai.</description><link>http://xcodenoobies.blogspot.com/2017/02/how-to-create-undo-and-redo-in-drawing.html</link><author>noreply@blogger.com (GeneCode)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-3170154019646749026</guid><pubDate>Sun, 04 Dec 2016 11:37:00 +0000</pubDate><atom:updated>2016-12-04T03:42:21.106-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">calendar</category><category domain="http://www.blogger.com/atom/ns#">custom</category><category domain="http://www.blogger.com/atom/ns#">inherit</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">object</category><category domain="http://www.blogger.com/atom/ns#">subclass</category><category domain="http://www.blogger.com/atom/ns#">tutorial</category><title>How To: Create Custom Objects in iOS Apps</title><description>Hey guys. Another noobies tutorial!!!!! First, an intro. My latest app just been approved by Apple so I guess I will write about that (HA!! :P) The app is called &lt;b&gt;QuikFlix&lt;/b&gt;. It is a movie database app. I made the app because I needed it. I was always trying to find old movies that I want to watch. For example, particularly, I wanted to find top/popular comedy movies in 2013. How do you go about finding that? Google works I guess. But navigating in browser really sucks. So I created QuikFlix with all the features that I WANT: &lt;b&gt;Search movies by Genre, Year and Popularity&lt;/b&gt;. Plus, I added main casts list in there with movie synopsis. And you can easily see photo of the cast by tapping on their name. AND I also create a simple WishList so you can add movies you want to watch in this list. AND!!! I also added theme color. It is free app check it out here:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://itunes.apple.com/by/app/quikflix/id1169970723?mt=8"&gt;https://itunes.apple.com/by/app/quikflix/id1169970723?mt=8&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I used TheMovieDB.com public API for this app. Their API is really good in my opinion. You can do a lot more actually (like have user accounts, rating ability).&lt;br /&gt;
&lt;br /&gt;
Anyway intro finished, Lets begin tutorial. :D Here is what we're gonna make:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOuNObx812PNpjzFUQ5M6syZqPKHuf2AjJ78VpeONGHz3wm6BK_l625aqnNTOMTxZmJrec0-EzpOFx5-4lXQhs4TiAm1wCTJT3TyejdBC8b79a3j5LUx0x1GaaIjIwqDaDwupncyPvlvU/s1600/Dec-04-2016+19-32-04.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="327" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOuNObx812PNpjzFUQ5M6syZqPKHuf2AjJ78VpeONGHz3wm6BK_l625aqnNTOMTxZmJrec0-EzpOFx5-4lXQhs4TiAm1wCTJT3TyejdBC8b79a3j5LUx0x1GaaIjIwqDaDwupncyPvlvU/s400/Dec-04-2016+19-32-04.gif" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Cool huh? Btw, the more accurate title for this tutorial is "How to Subclass / Inherit an Object", but those words are intimidating aren't they? What does subclass means? &lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Well, it is simple, think of it like this - a factory produces a type of Computer Motherboard. You as a desktop PC seller, take this motherboard, add things on it, peripherals and what not, and voila you have your own desktop. Subclassing is much like this. The readily available objects in UIKit are like the computer motherboards in factory. You take that object, add stuff on it, make it do additional things and voila you have a "new" object.&lt;br /&gt;
&lt;br /&gt;
To show you wonderful programmers how to subclass an object, we need to decide what to make first. Something easy but cool. We shall make a component for a calendar. A typical square with Day and Date, and we can tap on it to toggle the background color. With this object, we will make a month calendar. We will also try to make it support multi orientation so it appears nice in landscape or portrait.&lt;br /&gt;
&lt;br /&gt;
First, create a single view application in XCode.&lt;br /&gt;
&lt;br /&gt;
Next, right click on the Project Navigator panel and select New File... from menu. In the next window, select &lt;b&gt;Cocoa Touch Class&lt;/b&gt; and click Next. Choose a name for it (in this case I name it "DayView") and select Class of &lt;b&gt;UIView&lt;/b&gt; and click on Create button. You will see two files added to your Project - DayView.m and DayView.h.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZq1VXSyEImozn6DxtDAKDyUmmjj9pImNh4cLsOLTsVdjkCb61SPFTWHTKu-Huy-1txNIW3zY0CW4V_yTrqvKTsuKZaftyOl-PVz6lpLkIl68l4WyprxcKkpympuC4BID1BQxOLsI9V2k/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="229" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZq1VXSyEImozn6DxtDAKDyUmmjj9pImNh4cLsOLTsVdjkCb61SPFTWHTKu-Huy-1txNIW3zY0CW4V_yTrqvKTsuKZaftyOl-PVz6lpLkIl68l4WyprxcKkpympuC4BID1BQxOLsI9V2k/s320/Untitled.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Next, right click again the Project Navigator panel and choose New File... and this time, go to Resources in the left panel, and select View on the right panel. Click Next and name it DayView. You will see a DayView.xib file created in your project.&lt;br /&gt;
&lt;br /&gt;
Now here is the important step to link between your Custom Class DayView.m/h and the DayView.xib you just created:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
Click on DayView.xib's view and go to Object Inspector, and in Class textfield, type "DayView". Then press Return.&lt;/blockquote&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyufWWz4UBl1x3RukjdFUDRW4Ur6nUmiqghmoeck4H_8cf3v0BPwKfbbQXI6KBdROgCpCwvWUj7409QUbo1bN0Wpi6DpXFarOWFLG6CVIk5qFUpMPSKoYhtx_EKb63urep7KTITG54GwQ/s1600/Untitled2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyufWWz4UBl1x3RukjdFUDRW4Ur6nUmiqghmoeck4H_8cf3v0BPwKfbbQXI6KBdROgCpCwvWUj7409QUbo1bN0Wpi6DpXFarOWFLG6CVIk5qFUpMPSKoYhtx_EKb63urep7KTITG54GwQ/s200/Untitled2.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Next, add 2 UILabels on the DayView.xib. One will be used as the calendar "Header" where it will display Days (Sun, Mon, Tue, etc), and the other will be used to display the Date itself. Add the appropriate Constraints as you want. Here, I align the day label at the top left. and the date label at the bottom right. Then connect these 2 labels as IBOutlets in the DayView.h file.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilE95xBkOM1rK42XVG6ir6GldSGS2CJiSv_P-Cj9-qBAa2PxfDkLOQtre44f81-gADiofg53PphOR-Bo8dWZn4vZTX0716bCIlXNH41NVy08jv9Vt1RA63fyjv0G7Mu1D0IYvlhshccfk/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilE95xBkOM1rK42XVG6ir6GldSGS2CJiSv_P-Cj9-qBAa2PxfDkLOQtre44f81-gADiofg53PphOR-Bo8dWZn4vZTX0716bCIlXNH41NVy08jv9Vt1RA63fyjv0G7Mu1D0IYvlhshccfk/s1600/3.png" /&gt;&lt;/a&gt;&lt;/div&gt;
You can add any object in here- for example, a UIImageView for background of the day cell, or another UIViews etc. Next, we need to write the init method for this DayView class. Enter the following code in DayView.m:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
- (id)init
{
    self = [super init];
    if (self) {
        
        NSArray *arr =  [[NSBundle mainBundle] loadNibNamed:@"DayView" owner:self options:nil];
        self = [arr objectAtIndex:0];
        mode = 1;
        
    }
    return self;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
What we do here is simple, we load the Xib file and return self in init method. So when the controller init this class, they will get the xib object as we have designed in storyboard. There is also a variable "mode" that I initialize here. "mode" is just an integer to be used to keep track of which day rect is being touched. If you require any more values/parameters to each "day", you can add them in the DayView.h file as properties, and synthesizing them in .m file. And then initialize their values in this init method.&lt;br /&gt;
&lt;br /&gt;
Next, implement the touches delegate in this DayView and do the necessary changes when user tap on the day object. Here I simply toggle the background color Green&amp;lt;----&amp;gt;White.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(void)touchesBegan:(NSSet&amp;lt;UITouch *&amp;gt; *)touches withEvent:(UIEvent *)event {
    
    if (mode==1) {
        mode = 2;
        self.backgroundColor = [UIColor greenColor];
    } else {
        mode = 1;
        self.backgroundColor = [UIColor whiteColor];
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Now, in our main ViewController, we can already use our custom class by creating them in viewDidLoad.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
    // create all dayviews
    for (int i = 0; i&amp;lt;35; i++) {
        
        DayView *dv = [[DayView alloc] init];
        dv.tag = 100+i;
        [self.view addSubview:dv];
        
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
This code isn't complete. But this is how you create the custom class and add it to your view. You alloc and init it. Assign tag (so you can reuse it in other methods in the viewController), and add it to the view.&lt;br /&gt;
&lt;br /&gt;
You also need to set the labels texts (can be accessed by using &lt;b&gt;dv.dateLabel.text = @"12";&lt;/b&gt;&amp;nbsp;for example). I had to hardcode the total days in the month in this tutorial &amp;nbsp;project so you will get the idea how to use the custom object. You need to work out how to assign the date/days of the actual month by yourself.&lt;br /&gt;
&lt;br /&gt;
The final part is to resize and reposition the DayView object:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
-(void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    
    // reposition and resize
    CGFloat wid = [[UIScreen mainScreen] bounds].size.width / 7.0;
    
    CGFloat xOffset = 0;
    CGFloat yOffset = 50;
    CGFloat dayHeight = 60;
    
    for (int i = 0; i&amp;lt;35; i++) {
        
        if ((i%7==0)&amp;amp;&amp;amp;(i!=0)) {
            xOffset = 0;
            yOffset += dayHeight;
        }
     
        DayView *dv = (DayView*)[self.view viewWithTag:i+100];
        dv.frame = CGRectMake(xOffset, yOffset, wid, dayHeight);
        xOffset += wid;
    }
    
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
viewDidLayoutSubviews is the View Delegates. This particular delegate gets called a lot, and it will get called when you rotate your device to landscape/portrait. It is a perfect place to resize/reposition your DayView objects.&lt;br /&gt;
&lt;br /&gt;
That's all there is to it. Congrats now you have a month worth of calendar by using custom DayView object. Download the whole project by clicking icon below:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://www.dropbox.com/s/f6h6ityubbuzsii/dayView.zip?dl=0"&gt;&lt;img border="0" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJxG0OiR4I5cgBN5SVtYoQvK4JjHyT-EsRjiDs6Mu8MH_mPgcSoDbpQmPK6jn8bpdTw9vdrj_QZ24_lqOwr8DvRqS-s7KRYw1egiWp1QcukVoy7tu3bEdU1myqnW_nrXXm7gdhunCWdy8/s320/download.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://xcodenoobies.blogspot.com/2016/12/how-to-create-custom-objects-in-ios-apps.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOuNObx812PNpjzFUQ5M6syZqPKHuf2AjJ78VpeONGHz3wm6BK_l625aqnNTOMTxZmJrec0-EzpOFx5-4lXQhs4TiAm1wCTJT3TyejdBC8b79a3j5LUx0x1GaaIjIwqDaDwupncyPvlvU/s72-c/Dec-04-2016+19-32-04.gif" width="72"/><thr:total>1</thr:total><enclosure length="-1" type="application/json" url="https://www.dropbox.com/s/f6h6ityubbuzsii/dayView.zip?dl=0"/><itunes:explicit/><itunes:subtitle>Hey guys. Another noobies tutorial!!!!! First, an intro. My latest app just been approved by Apple so I guess I will write about that (HA!! :P) The app is called QuikFlix. It is a movie database app. I made the app because I needed it. I was always trying to find old movies that I want to watch. For example, particularly, I wanted to find top/popular comedy movies in 2013. How do you go about finding that? Google works I guess. But navigating in browser really sucks. So I created QuikFlix with all the features that I WANT: Search movies by Genre, Year and Popularity. Plus, I added main casts list in there with movie synopsis. And you can easily see photo of the cast by tapping on their name. AND I also create a simple WishList so you can add movies you want to watch in this list. AND!!! I also added theme color. It is free app check it out here: https://itunes.apple.com/by/app/quikflix/id1169970723?mt=8 I used TheMovieDB.com public API for this app. Their API is really good in my opinion. You can do a lot more actually (like have user accounts, rating ability). Anyway intro finished, Lets begin tutorial. :D Here is what we're gonna make: Cool huh? Btw, the more accurate title for this tutorial is "How to Subclass / Inherit an Object", but those words are intimidating aren't they? What does subclass means? Well, it is simple, think of it like this - a factory produces a type of Computer Motherboard. You as a desktop PC seller, take this motherboard, add things on it, peripherals and what not, and voila you have your own desktop. Subclassing is much like this. The readily available objects in UIKit are like the computer motherboards in factory. You take that object, add stuff on it, make it do additional things and voila you have a "new" object. To show you wonderful programmers how to subclass an object, we need to decide what to make first. Something easy but cool. We shall make a component for a calendar. A typical square with Day and Date, and we can tap on it to toggle the background color. With this object, we will make a month calendar. We will also try to make it support multi orientation so it appears nice in landscape or portrait. First, create a single view application in XCode. Next, right click on the Project Navigator panel and select New File... from menu. In the next window, select Cocoa Touch Class and click Next. Choose a name for it (in this case I name it "DayView") and select Class of UIView and click on Create button. You will see two files added to your Project - DayView.m and DayView.h. Next, right click again the Project Navigator panel and choose New File... and this time, go to Resources in the left panel, and select View on the right panel. Click Next and name it DayView. You will see a DayView.xib file created in your project. Now here is the important step to link between your Custom Class DayView.m/h and the DayView.xib you just created: Click on DayView.xib's view and go to Object Inspector, and in Class textfield, type "DayView". Then press Return. Next, add 2 UILabels on the DayView.xib. One will be used as the calendar "Header" where it will display Days (Sun, Mon, Tue, etc), and the other will be used to display the Date itself. Add the appropriate Constraints as you want. Here, I align the day label at the top left. and the date label at the bottom right. Then connect these 2 labels as IBOutlets in the DayView.h file. You can add any object in here- for example, a UIImageView for background of the day cell, or another UIViews etc. Next, we need to write the init method for this DayView class. Enter the following code in DayView.m: - (id)init { self = [super init]; if (self) { NSArray *arr = [[NSBundle mainBundle] loadNibNamed:@"DayView" owner:self options:nil]; self = [arr objectAtIndex:0]; mode = 1; } return self; } What we do here is simple, we load the Xib file and return self in init method. So when the controller init this class, they will get the xib object as we have designed in storyboard. There is also a variable "mode" that I initialize here. "mode" is just an integer to be used to keep track of which day rect is being touched. If you require any more values/parameters to each "day", you can add them in the DayView.h file as properties, and synthesizing them in .m file. And then initialize their values in this init method. Next, implement the touches delegate in this DayView and do the necessary changes when user tap on the day object. Here I simply toggle the background color Green&amp;lt;----&amp;gt;White. -(void)touchesBegan:(NSSet&amp;lt;UITouch *&amp;gt; *)touches withEvent:(UIEvent *)event { if (mode==1) { mode = 2; self.backgroundColor = [UIColor greenColor]; } else { mode = 1; self.backgroundColor = [UIColor whiteColor]; } } Now, in our main ViewController, we can already use our custom class by creating them in viewDidLoad. // create all dayviews for (int i = 0; i&amp;lt;35; i++) { DayView *dv = [[DayView alloc] init]; dv.tag = 100+i; [self.view addSubview:dv]; } This code isn't complete. But this is how you create the custom class and add it to your view. You alloc and init it. Assign tag (so you can reuse it in other methods in the viewController), and add it to the view. You also need to set the labels texts (can be accessed by using dv.dateLabel.text = @"12";&amp;nbsp;for example). I had to hardcode the total days in the month in this tutorial &amp;nbsp;project so you will get the idea how to use the custom object. You need to work out how to assign the date/days of the actual month by yourself. The final part is to resize and reposition the DayView object: -(void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; // reposition and resize CGFloat wid = [[UIScreen mainScreen] bounds].size.width / 7.0; CGFloat xOffset = 0; CGFloat yOffset = 50; CGFloat dayHeight = 60; for (int i = 0; i&amp;lt;35; i++) { if ((i%7==0)&amp;amp;&amp;amp;(i!=0)) { xOffset = 0; yOffset += dayHeight; } DayView *dv = (DayView*)[self.view viewWithTag:i+100]; dv.frame = CGRectMake(xOffset, yOffset, wid, dayHeight); xOffset += wid; } } viewDidLayoutSubviews is the View Delegates. This particular delegate gets called a lot, and it will get called when you rotate your device to landscape/portrait. It is a perfect place to resize/reposition your DayView objects. That's all there is to it. Congrats now you have a month worth of calendar by using custom DayView object. Download the whole project by clicking icon below:</itunes:subtitle><itunes:author>noreply@blogger.com (GeneCode)</itunes:author><itunes:summary>Hey guys. Another noobies tutorial!!!!! First, an intro. My latest app just been approved by Apple so I guess I will write about that (HA!! :P) The app is called QuikFlix. It is a movie database app. I made the app because I needed it. I was always trying to find old movies that I want to watch. For example, particularly, I wanted to find top/popular comedy movies in 2013. How do you go about finding that? Google works I guess. But navigating in browser really sucks. So I created QuikFlix with all the features that I WANT: Search movies by Genre, Year and Popularity. Plus, I added main casts list in there with movie synopsis. And you can easily see photo of the cast by tapping on their name. AND I also create a simple WishList so you can add movies you want to watch in this list. AND!!! I also added theme color. It is free app check it out here: https://itunes.apple.com/by/app/quikflix/id1169970723?mt=8 I used TheMovieDB.com public API for this app. Their API is really good in my opinion. You can do a lot more actually (like have user accounts, rating ability). Anyway intro finished, Lets begin tutorial. :D Here is what we're gonna make: Cool huh? Btw, the more accurate title for this tutorial is "How to Subclass / Inherit an Object", but those words are intimidating aren't they? What does subclass means? Well, it is simple, think of it like this - a factory produces a type of Computer Motherboard. You as a desktop PC seller, take this motherboard, add things on it, peripherals and what not, and voila you have your own desktop. Subclassing is much like this. The readily available objects in UIKit are like the computer motherboards in factory. You take that object, add stuff on it, make it do additional things and voila you have a "new" object. To show you wonderful programmers how to subclass an object, we need to decide what to make first. Something easy but cool. We shall make a component for a calendar. A typical square with Day and Date, and we can tap on it to toggle the background color. With this object, we will make a month calendar. We will also try to make it support multi orientation so it appears nice in landscape or portrait. First, create a single view application in XCode. Next, right click on the Project Navigator panel and select New File... from menu. In the next window, select Cocoa Touch Class and click Next. Choose a name for it (in this case I name it "DayView") and select Class of UIView and click on Create button. You will see two files added to your Project - DayView.m and DayView.h. Next, right click again the Project Navigator panel and choose New File... and this time, go to Resources in the left panel, and select View on the right panel. Click Next and name it DayView. You will see a DayView.xib file created in your project. Now here is the important step to link between your Custom Class DayView.m/h and the DayView.xib you just created: Click on DayView.xib's view and go to Object Inspector, and in Class textfield, type "DayView". Then press Return. Next, add 2 UILabels on the DayView.xib. One will be used as the calendar "Header" where it will display Days (Sun, Mon, Tue, etc), and the other will be used to display the Date itself. Add the appropriate Constraints as you want. Here, I align the day label at the top left. and the date label at the bottom right. Then connect these 2 labels as IBOutlets in the DayView.h file. You can add any object in here- for example, a UIImageView for background of the day cell, or another UIViews etc. Next, we need to write the init method for this DayView class. Enter the following code in DayView.m: - (id)init { self = [super init]; if (self) { NSArray *arr = [[NSBundle mainBundle] loadNibNamed:@"DayView" owner:self options:nil]; self = [arr objectAtIndex:0]; mode = 1; } return self; } What we do here is simple, we load the Xib file and return self in init method. So when the controller init this class, they will get the xib object as we have designed in storyboard. There is also a variable "mode" that I initialize here. "mode" is just an integer to be used to keep track of which day rect is being touched. If you require any more values/parameters to each "day", you can add them in the DayView.h file as properties, and synthesizing them in .m file. And then initialize their values in this init method. Next, implement the touches delegate in this DayView and do the necessary changes when user tap on the day object. Here I simply toggle the background color Green&amp;lt;----&amp;gt;White. -(void)touchesBegan:(NSSet&amp;lt;UITouch *&amp;gt; *)touches withEvent:(UIEvent *)event { if (mode==1) { mode = 2; self.backgroundColor = [UIColor greenColor]; } else { mode = 1; self.backgroundColor = [UIColor whiteColor]; } } Now, in our main ViewController, we can already use our custom class by creating them in viewDidLoad. // create all dayviews for (int i = 0; i&amp;lt;35; i++) { DayView *dv = [[DayView alloc] init]; dv.tag = 100+i; [self.view addSubview:dv]; } This code isn't complete. But this is how you create the custom class and add it to your view. You alloc and init it. Assign tag (so you can reuse it in other methods in the viewController), and add it to the view. You also need to set the labels texts (can be accessed by using dv.dateLabel.text = @"12";&amp;nbsp;for example). I had to hardcode the total days in the month in this tutorial &amp;nbsp;project so you will get the idea how to use the custom object. You need to work out how to assign the date/days of the actual month by yourself. The final part is to resize and reposition the DayView object: -(void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; // reposition and resize CGFloat wid = [[UIScreen mainScreen] bounds].size.width / 7.0; CGFloat xOffset = 0; CGFloat yOffset = 50; CGFloat dayHeight = 60; for (int i = 0; i&amp;lt;35; i++) { if ((i%7==0)&amp;amp;&amp;amp;(i!=0)) { xOffset = 0; yOffset += dayHeight; } DayView *dv = (DayView*)[self.view viewWithTag:i+100]; dv.frame = CGRectMake(xOffset, yOffset, wid, dayHeight); xOffset += wid; } } viewDidLayoutSubviews is the View Delegates. This particular delegate gets called a lot, and it will get called when you rotate your device to landscape/portrait. It is a perfect place to resize/reposition your DayView objects. That's all there is to it. Congrats now you have a month worth of calendar by using custom DayView object. Download the whole project by clicking icon below:</itunes:summary><itunes:keywords>calendar, custom, inherit, ios, object, subclass, tutorial</itunes:keywords></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-8674086436588520475</guid><pubDate>Sun, 27 Nov 2016 10:39:00 +0000</pubDate><atom:updated>2016-11-27T02:50:55.299-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">embed</category><category domain="http://www.blogger.com/atom/ns#">in</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">skview</category><category domain="http://www.blogger.com/atom/ns#">Spritekit</category><category domain="http://www.blogger.com/atom/ns#">uiview</category><category domain="http://www.blogger.com/atom/ns#">uiviewcontroller</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><title>How To: Embed SpriteKit In UIViewController</title><description>Time for another simple iOS Tutorial!&lt;br /&gt;
&lt;br /&gt;
First, a witty intro. It is not always best to be the first. Sometimes, being last is best.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh30wUD_CfeaRc-Fuw1IxrQs0b2QFLLLo9Cj6s_Fl-vfWtfHp_xDjPt9FFegYNMoFvLf-YJEHjJbEA1QXXi0_A9A44KSlRIXGhKSjMg1Gnk1omaChBS8wVCT4Ntijb46H57yai255kpFVY/s1600/8cec2e90ac80a116a1c6613950c98a3d.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh30wUD_CfeaRc-Fuw1IxrQs0b2QFLLLo9Cj6s_Fl-vfWtfHp_xDjPt9FFegYNMoFvLf-YJEHjJbEA1QXXi0_A9A44KSlRIXGhKSjMg1Gnk1omaChBS8wVCT4Ntijb46H57yai255kpFVY/s320/8cec2e90ac80a116a1c6613950c98a3d.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
Ok, Lets get on with the tutorial then. It is really easy to add a spritekit scene in your viewcontroller. All you gotta do is add a UIView and change its class to SKView and add a scene to that SKView in the viewController.&lt;br /&gt;
&lt;br /&gt;
Ok, thanks bye.&lt;br /&gt;
&lt;br /&gt;
That'd be the shortest tutorial I ever wrote if that was the end of it. Relax. Here is how to do it, step by step. First, create a New Project. For simplicity sake, just create a single view application.&lt;br /&gt;
&lt;br /&gt;
Next, open the Main.storyboard and add a UIView on it. Change its background color so you could see it better. The background color won't matter since this view will only act as a "container" to the SpriteKit view.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH54eBYrJTgxbcz5z6Orkqb31S2wigUcWpDn5hNJc1x5rMnRJbXTPY2w24RZYPV1_gCUuW1m05hY0QIclF5vFUzBwimf_lOfRMJbMxAF7uv4y36XhNwYJAwI3_6qsR1Dij0pDv1rlisMY/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="390" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH54eBYrJTgxbcz5z6Orkqb31S2wigUcWpDn5hNJc1x5rMnRJbXTPY2w24RZYPV1_gCUuW1m05hY0QIclF5vFUzBwimf_lOfRMJbMxAF7uv4y36XhNwYJAwI3_6qsR1Dij0pDv1rlisMY/s400/Untitled.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
The gray color rectangle is the UIView we added earlier. The other objects I added just to show that this is just a normal UIViewController, thus you can add any UIKit objects on it like UILabel, UISwitch and so on. I also added constraints for the gray UIView so that it stays at the bottom (sorta status bar-like design). You can put it anywhere you like.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq"&gt;
Now, before you do anything else, add the SpriteKit.framework to your project. This is really important (DUHH).&lt;/blockquote&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh64zBFhuYVLm4-uj8h9MewbwkFkQD3YEz5p_yh3biaKKxDvFsuqhwc0H28slQ_prWXUAn9sDNh8UkIydLDnOLiC6L8-A3D0loboYL4Io3xy-BmjDDj1UcwiePczFsUw4a-72FZrDbkEKI/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="144" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh64zBFhuYVLm4-uj8h9MewbwkFkQD3YEz5p_yh3biaKKxDvFsuqhwc0H28slQ_prWXUAn9sDNh8UkIydLDnOLiC6L8-A3D0loboYL4Io3xy-BmjDDj1UcwiePczFsUw4a-72FZrDbkEKI/s320/3.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
After you done this, go back to the Storyboard and select your gray UIView and open the &lt;b&gt;Identity Inspector&lt;/b&gt; and in the Class textfield, enter "SKView" and press return. You should end up with the following:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxZ0zJeG-VfdQlABZ88rIqj27ihjASG6silZVZG28N2fiFjfI1-6tltGO7d3aSrQ2sP-gTlCXZLMb5-6m9dcat6-9XB3GxRiBi-BeTxnoRvefH6n4yFRMJyJGYJJF7wHYinA_v4PpA5qo/s1600/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxZ0zJeG-VfdQlABZ88rIqj27ihjASG6silZVZG28N2fiFjfI1-6tltGO7d3aSrQ2sP-gTlCXZLMb5-6m9dcat6-9XB3GxRiBi-BeTxnoRvefH6n4yFRMJyJGYJJF7wHYinA_v4PpA5qo/s320/2.png" width="216" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
This will make the UIView "become" the SKView and inherit all of its methods and properties. You don't really need to subclass the SKView (unless you want to do something else that's up to you).&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Next, is to create an outlet for this "SKView". So click on Assistant editor, control click on the "SKView" and drag to the ViewController.h and name it "skView." There probably will be an error to it. Somehow XCode assign the skView type to "SpriteKit". Change that to SKView instead. Your IBOutlet should be like below:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

@property (weak, nonatomic) IBOutlet SKView *skView;

&lt;/code&gt;&lt;/pre&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
After that, you need to add an SKScene to your project. To do that, right click on the Project Navigator on the left and choose New File... select Cocoa Touch Class, click Next and create a new class of SKScene as below:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiklahi6w4dvjIkKdE_rmY3cIQ0KLPpnrv2_kEkOCY8XPRC6t4uawLxgkio56CFn-7KClr1JQAXMiYDy911GOAdwpXF70ZzoMS48fYhLAx1RRVo3aiqUt-WsnwtRnfOHMNOcSFw_NvyGd4/s1600/4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiklahi6w4dvjIkKdE_rmY3cIQ0KLPpnrv2_kEkOCY8XPRC6t4uawLxgkio56CFn-7KClr1JQAXMiYDy911GOAdwpXF70ZzoMS48fYhLAx1RRVo3aiqUt-WsnwtRnfOHMNOcSFw_NvyGd4/s320/4.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Click Next and click Create on the next dialog window. You will see there will be 2 new files added to your Project Navigator on the left panel of XCode - MyScene.h and MyScene.m.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Now open ViewController.m, and import MyScene.h. And in the viewDidload delegate method, add the following code:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

    SKScene * scene = [MyScene sceneWithSize:_skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;
    
    // Present the scene.
    [_skView presentScene:scene];

&lt;/code&gt;&lt;/pre&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
And that is all there is to it! You have basically completed adding a SpriteKit scene into your viewcontroller. Of course, the scene is now empty, so you'll just see a black colored rectangle at the bottom.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
I went ahead and create a simple scene where it scrolls randomly colored words (as SKLabelNode) from right to left. The words are hardcoded as objects in an NSArray in the Scene (open up Scene.m) to see.&amp;nbsp;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
And the result:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtZdacf8Kl88zh_EEDFv2_y44p551x5f7A1wHSOh5J4N24UDsYHhHNfweJt5sOFXf_tX5Ysm4zjXw84edDKEaGC1IdQkMnVNJUKhgyPKnVRsQPKx7oFP44ZENX0N4MQhjkjNYM9LNe8yA/s1600/Nov-27-2016+18-31-27.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtZdacf8Kl88zh_EEDFv2_y44p551x5f7A1wHSOh5J4N24UDsYHhHNfweJt5sOFXf_tX5Ysm4zjXw84edDKEaGC1IdQkMnVNJUKhgyPKnVRsQPKx7oFP44ZENX0N4MQhjkjNYM9LNe8yA/s320/Nov-27-2016+18-31-27.gif" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
(it's a GIF image 3.5MB may take a while)&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;a href="https://www.dropbox.com/s/ecm5darbuwmnaii/textScroller.zip?dl=0"&gt;&lt;img border="0" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJxG0OiR4I5cgBN5SVtYoQvK4JjHyT-EsRjiDs6Mu8MH_mPgcSoDbpQmPK6jn8bpdTw9vdrj_QZ24_lqOwr8DvRqS-s7KRYw1egiWp1QcukVoy7tu3bEdU1myqnW_nrXXm7gdhunCWdy8/s320/download.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://xcodenoobies.blogspot.com/2016/11/how-to-embed-spritekit-in.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh30wUD_CfeaRc-Fuw1IxrQs0b2QFLLLo9Cj6s_Fl-vfWtfHp_xDjPt9FFegYNMoFvLf-YJEHjJbEA1QXXi0_A9A44KSlRIXGhKSjMg1Gnk1omaChBS8wVCT4Ntijb46H57yai255kpFVY/s72-c/8cec2e90ac80a116a1c6613950c98a3d.jpg" width="72"/><thr:total>1</thr:total><enclosure length="-1" type="application/json" url="https://www.dropbox.com/s/ecm5darbuwmnaii/textScroller.zip?dl=0"/><itunes:explicit/><itunes:subtitle>Time for another simple iOS Tutorial! First, a witty intro. It is not always best to be the first. Sometimes, being last is best. Ok, Lets get on with the tutorial then. It is really easy to add a spritekit scene in your viewcontroller. All you gotta do is add a UIView and change its class to SKView and add a scene to that SKView in the viewController. Ok, thanks bye. That'd be the shortest tutorial I ever wrote if that was the end of it. Relax. Here is how to do it, step by step. First, create a New Project. For simplicity sake, just create a single view application. Next, open the Main.storyboard and add a UIView on it. Change its background color so you could see it better. The background color won't matter since this view will only act as a "container" to the SpriteKit view. The gray color rectangle is the UIView we added earlier. The other objects I added just to show that this is just a normal UIViewController, thus you can add any UIKit objects on it like UILabel, UISwitch and so on. I also added constraints for the gray UIView so that it stays at the bottom (sorta status bar-like design). You can put it anywhere you like. Now, before you do anything else, add the SpriteKit.framework to your project. This is really important (DUHH). After you done this, go back to the Storyboard and select your gray UIView and open the Identity Inspector and in the Class textfield, enter "SKView" and press return. You should end up with the following: This will make the UIView "become" the SKView and inherit all of its methods and properties. You don't really need to subclass the SKView (unless you want to do something else that's up to you). Next, is to create an outlet for this "SKView". So click on Assistant editor, control click on the "SKView" and drag to the ViewController.h and name it "skView." There probably will be an error to it. Somehow XCode assign the skView type to "SpriteKit". Change that to SKView instead. Your IBOutlet should be like below: @property (weak, nonatomic) IBOutlet SKView *skView; After that, you need to add an SKScene to your project. To do that, right click on the Project Navigator on the left and choose New File... select Cocoa Touch Class, click Next and create a new class of SKScene as below: Click Next and click Create on the next dialog window. You will see there will be 2 new files added to your Project Navigator on the left panel of XCode - MyScene.h and MyScene.m. Now open ViewController.m, and import MyScene.h. And in the viewDidload delegate method, add the following code: SKScene * scene = [MyScene sceneWithSize:_skView.bounds.size]; scene.scaleMode = SKSceneScaleModeAspectFill; // Present the scene. [_skView presentScene:scene]; And that is all there is to it! You have basically completed adding a SpriteKit scene into your viewcontroller. Of course, the scene is now empty, so you'll just see a black colored rectangle at the bottom. I went ahead and create a simple scene where it scrolls randomly colored words (as SKLabelNode) from right to left. The words are hardcoded as objects in an NSArray in the Scene (open up Scene.m) to see.&amp;nbsp; And the result: (it's a GIF image 3.5MB may take a while)</itunes:subtitle><itunes:author>noreply@blogger.com (GeneCode)</itunes:author><itunes:summary>Time for another simple iOS Tutorial! First, a witty intro. It is not always best to be the first. Sometimes, being last is best. Ok, Lets get on with the tutorial then. It is really easy to add a spritekit scene in your viewcontroller. All you gotta do is add a UIView and change its class to SKView and add a scene to that SKView in the viewController. Ok, thanks bye. That'd be the shortest tutorial I ever wrote if that was the end of it. Relax. Here is how to do it, step by step. First, create a New Project. For simplicity sake, just create a single view application. Next, open the Main.storyboard and add a UIView on it. Change its background color so you could see it better. The background color won't matter since this view will only act as a "container" to the SpriteKit view. The gray color rectangle is the UIView we added earlier. The other objects I added just to show that this is just a normal UIViewController, thus you can add any UIKit objects on it like UILabel, UISwitch and so on. I also added constraints for the gray UIView so that it stays at the bottom (sorta status bar-like design). You can put it anywhere you like. Now, before you do anything else, add the SpriteKit.framework to your project. This is really important (DUHH). After you done this, go back to the Storyboard and select your gray UIView and open the Identity Inspector and in the Class textfield, enter "SKView" and press return. You should end up with the following: This will make the UIView "become" the SKView and inherit all of its methods and properties. You don't really need to subclass the SKView (unless you want to do something else that's up to you). Next, is to create an outlet for this "SKView". So click on Assistant editor, control click on the "SKView" and drag to the ViewController.h and name it "skView." There probably will be an error to it. Somehow XCode assign the skView type to "SpriteKit". Change that to SKView instead. Your IBOutlet should be like below: @property (weak, nonatomic) IBOutlet SKView *skView; After that, you need to add an SKScene to your project. To do that, right click on the Project Navigator on the left and choose New File... select Cocoa Touch Class, click Next and create a new class of SKScene as below: Click Next and click Create on the next dialog window. You will see there will be 2 new files added to your Project Navigator on the left panel of XCode - MyScene.h and MyScene.m. Now open ViewController.m, and import MyScene.h. And in the viewDidload delegate method, add the following code: SKScene * scene = [MyScene sceneWithSize:_skView.bounds.size]; scene.scaleMode = SKSceneScaleModeAspectFill; // Present the scene. [_skView presentScene:scene]; And that is all there is to it! You have basically completed adding a SpriteKit scene into your viewcontroller. Of course, the scene is now empty, so you'll just see a black colored rectangle at the bottom. I went ahead and create a simple scene where it scrolls randomly colored words (as SKLabelNode) from right to left. The words are hardcoded as objects in an NSArray in the Scene (open up Scene.m) to see.&amp;nbsp; And the result: (it's a GIF image 3.5MB may take a while)</itunes:summary><itunes:keywords>embed, in, ios, skview, Spritekit, uiview, uiviewcontroller, XCode</itunes:keywords></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-2373973657438063537</guid><pubDate>Sat, 19 Nov 2016 08:20:00 +0000</pubDate><atom:updated>2016-11-19T19:35:56.883-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cell</category><category domain="http://www.blogger.com/atom/ns#">custom</category><category domain="http://www.blogger.com/atom/ns#">object</category><category domain="http://www.blogger.com/atom/ns#">swipe</category><category domain="http://www.blogger.com/atom/ns#">swipeable</category><category domain="http://www.blogger.com/atom/ns#">tableview</category><category domain="http://www.blogger.com/atom/ns#">uitableviewcell</category><title>How To: Create Swipeable Tableview Cell with Any Objects</title><description>Here is what we're going to accomplish:&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-Ay017ybsEKjI0ni_paHWjCP-BR4yyca31mz-YIPQkHPlM77lBMhQAGSijKEZQsKAW1SBPQzuRRLLOU2d2ovrYm0UpbrDl52zx2gOb1Z3Vqfqf-ncTfsyrNdD6FSZdjlb4bHFxbCXdGk/s1600/Nov-19-2016+15-42-40.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-Ay017ybsEKjI0ni_paHWjCP-BR4yyca31mz-YIPQkHPlM77lBMhQAGSijKEZQsKAW1SBPQzuRRLLOU2d2ovrYm0UpbrDl52zx2gOb1Z3Vqfqf-ncTfsyrNdD6FSZdjlb4bHFxbCXdGk/s320/Nov-19-2016+15-42-40.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style="text-align: center;"&gt;
(May take a while to show: 3.3MB O_O)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: start;"&gt;
But first... digressing (as always)&lt;/div&gt;
&lt;div style="text-align: start;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: start;"&gt;
AW YISSS!&lt;/div&gt;
&lt;div style="text-align: start;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: start;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXmO1CGw7Rr0affNg2T1hHj_vQvo2Nz8GpbzRnSSWY2N0Bhol4q89_zKA07BDMkPvDa17OFbK_FMhkWO4SHwfEL9XiGBaiGzLerCG7UoDSgzhbvs_LNtB1FG-IRA8P7VmE_fGL_VeObd4/s1600/588.jpg" imageanchor="1"&gt;&lt;img border="0" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXmO1CGw7Rr0affNg2T1hHj_vQvo2Nz8GpbzRnSSWY2N0Bhol4q89_zKA07BDMkPvDa17OFbK_FMhkWO4SHwfEL9XiGBaiGzLerCG7UoDSgzhbvs_LNtB1FG-IRA8P7VmE_fGL_VeObd4/s320/588.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: start;"&gt;
&lt;br /&gt;
&lt;h3&gt;
Be The Bird - Happy With Breadcrumbs XD&lt;/h3&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: start;"&gt;
&lt;div style="text-align: left;"&gt;
Hey guys what's going on. Been a while since I last wrote any tutorial for you wonderful programmers. So today I found some time to write it. Something broke in my blog - the source code part doesn't appear as they should! I apologize but as I checked the code formatting widget sourcecode that was hosted on googledrive was removed by the owner! (WTF dude).&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Anyhow, I needed to change my blog layout design too - as you can see now my blog theme has changed. Many things on the blog didn't work well. For example, you need to open a blog post first before you can read/post comments and so on. So after hours of searching I found an okay-ish blog theme from the blogger standard themes. I feel simplest theme is the best. I still need to find a replacement for the code formatting widget tho. T_T&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Today I want to teach you how to make your UITableView cells swipeable. In iOS7 (or was it iOS8?), Apple introduce a new API to create swipeable tableview cells. But only limited to buttons (or "actions" as they call it). What if you want to have an image there? Well, if you want images, you still can assign image as the button's backgroundImage. But, what if you want a Switch there? Or TextView? Or &lt;b&gt;thingamabob&lt;/b&gt;? (I love this word - THINGAMABOB).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://www.dropbox.com/s/0sj2hldpghd7e95/swipeCell.zip?dl=0"&gt;&lt;img border="0" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwLxvdeV19GlIOwzASKbWSKhUwjBPNy2jxMLuw5rPaWHzsF1SOfJYjf_ENH8wqM3GOdC6-h8S_JLY2sPFMmZDH6-ITjy7jwshUUYhFuWCX9lIbvWoWh1J7s-ychzXOczOj_MzKWlH-hw/s320/download.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The only way to achieve that at the moment, is to CUSTOM CLASS the UITableViewCell. OR!!! OR YOU COULD USE LIBRARY! Yep, there are multiple awesome libraries for swipeable tableview cells created by awesome, generous, developers out there over at GITHUB and other places. However, if you use library, you will not learn so much. This is why I prefer to do things my own, because I want to learn how it works. And you learn best, by doing.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So lets go.&lt;br /&gt;
&lt;br /&gt;
First, create a single view application. Then you add a UITableView and set all the necessary constraints (sides and bottom to superview margin=0, and top margin to Top Layout guide). Then add a Prototype UITableViewCell on it. This is the cell that we're going to subclass.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM5a6g3AkyzJ62r2h67vYhmjiFxBuqI6R8E6GGUOmBuOe0hjiEZXCLB9bjp3UQw_K6HPDmiL86EW58BHECRoAB4lFZ7kCbdfZlVs799168FAcDFaG7Pwoxy5dGGBkyL9gN0prnbp1HMZc/s1600/Screen+Shot+2016-11-19+at+11.17.35+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="345" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM5a6g3AkyzJ62r2h67vYhmjiFxBuqI6R8E6GGUOmBuOe0hjiEZXCLB9bjp3UQw_K6HPDmiL86EW58BHECRoAB4lFZ7kCbdfZlVs799168FAcDFaG7Pwoxy5dGGBkyL9gN0prnbp1HMZc/s400/Screen+Shot+2016-11-19+at+11.17.35+AM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;b&gt;1. HOW TO SUBCLASS OBJECT?&lt;/b&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
If you don't know how to subclass an iOS object, tough luck! HAHAHAH! Ok jk, I will teach you here. It is quite an easy task. First, you decide what is the object that you want to subclass (ie customize)? Here, we are going to subclass UITableviewCell. So, Go to XCode and right click at your Project Navigator and select New File... then select "Cocoa Touch Class" under the iOS group. Then click Next.&amp;nbsp;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Then, in Subclass drop down menu, select UITableViewCell. Give a name of your new class - "SwipeTableViewCell". As you can see from the drop down menu, all iOS objects are listed here. You can subclass anything from here. Make sure you uncheck the "Also create XIB". We won't be needing a XIB since we already have the object in our storyboard.&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheqrd2ZtItgMWJFjqaBaFv9Z72OYTV5vwceeter-blWL9ZDr3f6gSky4GjVOTcLnxgXLBWTCoBZhsIANIZA5ZzXxhTsnuuF58TvCoR1oy1S97vbJ_p2snZGz-ROHnAuN6HMmrqDjaUAgQ/s1600/Screen+Shot+2016-11-19+at+11.27.13+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheqrd2ZtItgMWJFjqaBaFv9Z72OYTV5vwceeter-blWL9ZDr3f6gSky4GjVOTcLnxgXLBWTCoBZhsIANIZA5ZzXxhTsnuuF58TvCoR1oy1S97vbJ_p2snZGz-ROHnAuN6HMmrqDjaUAgQ/s320/Screen+Shot+2016-11-19+at+11.27.13+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Click Next and a dialog window will show requiring you to specify location to add the new class. Just click Create and then you will find 2 .m and .h files added to your project.&lt;br /&gt;
&lt;br /&gt;
The next step is Critical - assigning your tableviewcell in the storyboard to your newly created class:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGvefDa1tLe5ff1sGHvLEmQJLavH5CDvhV5dY6OZQAjze0NXf066MFBioYHdi1JovHOx2Ft_c6on4bgkMRZRfTh5Q2dU0kDsypp_VnZ1jpi5jWkQyxxsNyTBtSYU65btJtKEtgUgQseFs/s1600/Screen+Shot+2016-11-19+at+11.31.49+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="231" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGvefDa1tLe5ff1sGHvLEmQJLavH5CDvhV5dY6OZQAjze0NXf066MFBioYHdi1JovHOx2Ft_c6on4bgkMRZRfTh5Q2dU0kDsypp_VnZ1jpi5jWkQyxxsNyTBtSYU65btJtKEtgUgQseFs/s400/Screen+Shot+2016-11-19+at+11.31.49+AM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Observe the arrows. First, select your tableviewcell by clicking on the left panel (don't click on the storyboard object, because sometimes it will select tableview or the contentview instead). Then goto Identity Inspector on the right side panel, and enter your class name here. It should auto-complete by itself (if it doesn't autocomplete, it means you did not select a UITableViewCell object).&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
And... that is all there is to it! You are done subclassing a UITableViewCell!&amp;nbsp;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;b&gt;2. HOW TO CUSTOMIZE THE UITABLEVIEWCELL&lt;/b&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq" style="clear: both; text-align: left;"&gt;
If you already know how to subclass a tableviewcell, you may skip this section and go to section 3 below.&lt;/blockquote&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Now, lets customize this cell. As of now, all you did was subclass it but it is still the same old tableview. You need to add objects and codes to modify/customize the cell now. The basic uitableview cell provided by apple already can display items, but it is limited to a few texts - depending on the style of cell that we created.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoJXLNjXTnS_VCHNPxHvucvXhzEsEhyphenhyphenZWVGoEmAC-lx1tAPLFGwAwUsP5cihXLr3JyRSXyfKfDfYldzRQHlIeioUS-PyJqgjYDoukNNbkczczZcY617FDhRMu_cDAhkZRl3OrcPHK19uo/s1600/Screen+Shot+2016-11-19+at+11.40.07+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoJXLNjXTnS_VCHNPxHvucvXhzEsEhyphenhyphenZWVGoEmAC-lx1tAPLFGwAwUsP5cihXLr3JyRSXyfKfDfYldzRQHlIeioUS-PyJqgjYDoukNNbkczczZcY617FDhRMu_cDAhkZRl3OrcPHK19uo/s320/Screen+Shot+2016-11-19+at+11.40.07+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
By default, it is "Custom" (and you need to subclass tableviewcell). But if you don't want to subclass the cell, you can still use the default cell XCode provided - you can use &lt;b&gt;Basic&lt;/b&gt; (where there is one default label in it), or &lt;b&gt;Subtitle&lt;/b&gt; (where there are 2 labels in it). But these styles are fixed. You can't add images to the cell. Or other objects.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Now, lets make a decision - what to put in our table. For simplicity sake, lets create a fixed data system that resides in the app bundle (hence is read-only). I created a small database in database.plist file in the following format:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
[
   {
       Brand = "Honda"
       Model = "Fit"
       Price = "$10,000"
       Specs = "...&lt;multiple here="" line="" specs=""&gt;..."
    }
...
]
&lt;/multiple&gt;&lt;/code&gt;&lt;/pre&gt;
[ ] denotes array. and { } denotes dictionary.&lt;br /&gt;
&lt;br /&gt;
I added 5 entries with various car types. And then I search for these car images and change their name to match their Model (the "Model" field in the data above), and added them to the project's Images.xcasset. The purpose is so that we can load the image with command like:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

[UIImage imageNamed:[NSString stringWithFormat:@"%@.jpeg",[carDictionary objectForKey:@"Model"]]];

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;The plan is this:&lt;/b&gt; Display photo of car in each cells, with brand and model and price. And then user can swipe the cell to left side to reveal the car specs.&lt;br /&gt;
&lt;br /&gt;
First, lets add the necessary objects in our customcell and create all the necessary constraints (Yes! all objects need constraints even inside a tableview cell!). Then connect them to IBOutlets in our customcell header file.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKjUq1GXs7_IgIiU8WHOV9WtlVZFpPINs4qknyPmko93qQyo_ibppOjP5a23Aj76mo89Q0FYP-s-JjUP7BI8aavUbHiay6i4hyphenhyphen8MyWhmPS3vk-FmbJMvh2agRxFl80ivKe9XaGoGkN1PU/s1600/Screen+Shot+2016-11-19+at+12.35.30+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKjUq1GXs7_IgIiU8WHOV9WtlVZFpPINs4qknyPmko93qQyo_ibppOjP5a23Aj76mo89Q0FYP-s-JjUP7BI8aavUbHiay6i4hyphenhyphen8MyWhmPS3vk-FmbJMvh2agRxFl80ivKe9XaGoGkN1PU/s640/Screen+Shot+2016-11-19+at+12.35.30+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Now to load our database into the tableviewcell, we need to tell the Viewcontroller that our table is using it to load data. So lets do that - select our tableview and connect the &lt;b&gt;delegate&lt;/b&gt; and &lt;b&gt;datasource&lt;/b&gt; to our viewcontroller. We also connect tableview to a local property &lt;b&gt;carTable&lt;/b&gt; so we can access it easily.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy4iZ36CcfgFOWlOCO53-V469fejX2AxvKXJn6pjlkpvHOOlgA8JPaAbPRUnlz-4rsUCeZjRdxHmyhgDm6SHisOrqEi-JZvMKatLppIIA_bhAfEtRFKqDUh0HBGwt_4dXlr_LQWcq25VI/s1600/Screen+Shot+2016-11-19+at+12.44.27+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy4iZ36CcfgFOWlOCO53-V469fejX2AxvKXJn6pjlkpvHOOlgA8JPaAbPRUnlz-4rsUCeZjRdxHmyhgDm6SHisOrqEi-JZvMKatLppIIA_bhAfEtRFKqDUh0HBGwt_4dXlr_LQWcq25VI/s640/Screen+Shot+2016-11-19+at+12.44.27+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, lets create datasource for this table. A datasource is typically a NSMutableArray. NSMutableArray is synonym with tableview because both have indexes. Indexes are important because that is how data is ordered and arranged.&lt;br /&gt;
&lt;br /&gt;
Declare a &lt;b&gt;NSMutableArray *carDataArr &lt;/b&gt;and lets code loading our local database into this array.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"database" ofType:@"plist"];
    carDataArr = [[NSMutableArray alloc] initWithContentsOfFile:filePath];

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Next, we need to implement the tableView delegates so we can return this carDataArr as the table's datasource.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row % 2==0) {
        cell.contentView.backgroundColor = [UIColor colorWithHue:0 saturation:0 brightness:1.0 alpha:1];
    } else {
        cell.contentView.backgroundColor = [UIColor colorWithHue:0 saturation:0 brightness:0.9 alpha:1];
    
    }
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    return [carDataArr count];
    
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    SwipeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"swipeCellID"];
    if (cell==nil) {
     
        cell = [[SwipeTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"swipeCellID"];
    }
    
    NSDictionary *eachCarData = [carDataArr objectAtIndex:indexPath.row];
    cell.carBrand.text = [eachCarData objectForKey:@"Brand"];
    cell.carModel.text = [eachCarData objectForKey:@"Model"];
    cell.carPrice.text = [eachCarData objectForKey:@"Price"];
    cell.carPic.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.jpeg",[eachCarData objectForKey:@"Model"]]];
    
    return cell;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
And take a look at what we've accomplished so far!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgElDGeimIADV9yeGRA1bY5SgYsXtP_vDnRxV9v00opScEhAONYSBCe2vAVNy5Y8Hwk6Chs-PtITpdsJQm9STHPGQ1YG7Gm-Xq2WPpzYUhv52K9shA5PuE1i3sz9II6HrqjiyPeZinhi0I/s1600/Simulator+Screen+Shot+19+Nov+2016%252C+3.25.16+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgElDGeimIADV9yeGRA1bY5SgYsXtP_vDnRxV9v00opScEhAONYSBCe2vAVNy5Y8Hwk6Chs-PtITpdsJQm9STHPGQ1YG7Gm-Xq2WPpzYUhv52K9shA5PuE1i3sz9II6HrqjiyPeZinhi0I/s320/Simulator+Screen+Shot+19+Nov+2016%252C+3.25.16+PM.png" width="179" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we have all the data nicely displayed in the table. Congratulations! :D But wait, we have one more data to display: The car specs! As the tutorial intended: we need to make the cell swipable to left side and display the car spec behind the cell.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. SWIPEABLE CELL!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
To visualize how to make a cell swipable, take a look at the following diagram. In a UITableview (grey outline), there are many cells (blue outline) which conforms to its prototype. Inside each cells, there is a contentView (orange rectangle). What we can do is add subviews (green rectangle) behind this contentview and move the contentview to any direction and thus revealing the subview below it.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0uFFhrw14Dxa3-uMh-9os2mk7CnPGad9zql1RYkOnuMqbRgmrPh6-QpQYikXyNuP4DLIzTCEAdpFaNJr-3dyFRZ9GeBVCfEjAeFFZO8I0YO6Q7dxBTiLQLQ6UtX5liboX5ZBLAkQe4pI/s1600/tableviewStructure.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0uFFhrw14Dxa3-uMh-9os2mk7CnPGad9zql1RYkOnuMqbRgmrPh6-QpQYikXyNuP4DLIzTCEAdpFaNJr-3dyFRZ9GeBVCfEjAeFFZO8I0YO6Q7dxBTiLQLQ6UtX5liboX5ZBLAkQe4pI/s320/tableviewStructure.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
To achieve as the diagram, we need to add some codes to our custom cell class - &lt;b&gt;SwipeTableViewCell&lt;/b&gt;.m/.h. Inside the awakeFromNib, enter the following codes: (read the comments to understand what each portion does).&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;


- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
    
    CGRect containerFrame = self.contentView.frame;
    
    // create the textview and add to the contentview of the cell
    if (self.carSpecs==nil)
        self.carSpecs = [[UITextView alloc] initWithFrame:CGRectMake(containerFrame.size.width/2.0, containerFrame.origin.y,
                                                                       containerFrame.size.width/2.0, containerFrame.size.height)];
    
    [self.carSpecs setBackgroundColor:[UIColor clearColor]];
    [self setBackgroundColor:[UIColor colorWithRed:0.50 green:0.50 blue:0.50 alpha:1.00]];
    
    [self addSubview:self.carSpecs];
    [self sendSubviewToBack:self.carSpecs];
    
    // add the shadow to contentview to make it nicer
    self.contentView.layer.shadowColor = [[UIColor blackColor] CGColor];
    self.contentView.layer.shadowRadius = 5.0;
    self.contentView.layer.shadowOpacity = 1.0;
    self.contentView.layer.masksToBounds = NO;
    
    // CGFloat variable to track our cell movements
    _oriX = self.contentView.center.x;
    _xOffset =  self.contentView.center.x;
    
    // gesture recognizer to detect "swipe" which is actually panning
    UIPanGestureRecognizer *panLeft = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panLeftHandler:)];
    panLeft.delegate = self;
    
    self.gestureRecognizers = @[panLeft];
    
}

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
And then, we need to implement the gesture handler (ie what happens when user swipe our cell). Remember to add &amp;lt;UIGestureRecognizerDelegate&amp;gt; at SwipeTableViewCell.h. Then implement these 2 gesture recognizer delegate methods: (Again, read the comments to see what the code does)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
{
    
    _oriX = _xOffset; // reset the starting location of cell
    
    return YES;
}

-(void)panLeftHandler:(UIPanGestureRecognizer*)panGesture {
    
    UIView *cell = [panGesture view];
    CGPoint translation = [panGesture translationInView:[cell superview]];
    
    // this is called when user lift finger from screen
    if ([panGesture state]==UIGestureRecognizerStateEnded) {
        if (_xOffset&amp;lt;self.frame.size.width/4.0) {
            // if offset is below treshold, move cell to "open" open
            [UIView animateWithDuration:0.35 animations:^(void) {
                
                self.contentView.center = CGPointMake(0, self.contentView.center.y);
                
            }completion:^(BOOL finished) {
                
                _xOffset = self.contentView.center.x;
                
            }];
            
        } else {
            // if offset is above treshold, move cell to "close" position
            [UIView animateWithDuration:0.35 animations:^(void) {
                
                self.contentView.center = CGPointMake(self.center.x, self.contentView.center.y);
                
            }completion:^(BOOL finished) {
                
                _xOffset = self.contentView.center.x;
            }];
        }
        
    // the following is called when user keeps on panning finger on the cell
    } else {
        
        // the 50 pixels buffer is to prevent accidental swipes during tableview scrolling
        
        if ((translation.x&amp;gt;50)) {
            // here we update the offset and move the cell's contentview following user's finger
            
            _xOffset = _oriX+translation.x-50;
            self.contentView.center = CGPointMake(_xOffset, self.contentView.center.y);
            
        }
        
        if ((translation.x&amp;lt;-50)) {
            // here we update the offset and move the cell's contentview following user's finger
            
            _xOffset = _oriX+translation.x+50;
            self.contentView.center = CGPointMake(_xOffset, self.contentView.center.y);
            
        }
    }
}


&lt;/code&gt;&lt;/pre&gt;
Finally, go back to our ViewController and now we can populate our "Specs" data into the carSpecs UITextView. Add the following line to the &lt;b&gt;cellForRow&lt;/b&gt; delegate of our table.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

cell.carSpecs.text = [eachCarData objectForKey:@"Specs"];

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
And that's all there is to it. You can replace the UITextView with ANY KIND OF OBJECT as you like. Just be sure to create them programatically properly. You can put multiple objects too, and objects like UISwitch, UIImageView, heck even a ContainerView.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://www.dropbox.com/s/0sj2hldpghd7e95/swipeCell.zip?dl=0"&gt;&lt;img border="0" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwLxvdeV19GlIOwzASKbWSKhUwjBPNy2jxMLuw5rPaWHzsF1SOfJYjf_ENH8wqM3GOdC6-h8S_JLY2sPFMmZDH6-ITjy7jwshUUYhFuWCX9lIbvWoWh1J7s-ychzXOczOj_MzKWlH-hw/s320/download.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</description><link>http://xcodenoobies.blogspot.com/2016/11/how-to-create-swipeable-tableview-cell.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-Ay017ybsEKjI0ni_paHWjCP-BR4yyca31mz-YIPQkHPlM77lBMhQAGSijKEZQsKAW1SBPQzuRRLLOU2d2ovrYm0UpbrDl52zx2gOb1Z3Vqfqf-ncTfsyrNdD6FSZdjlb4bHFxbCXdGk/s72-c/Nov-19-2016+15-42-40.gif" width="72"/><thr:total>3</thr:total><enclosure length="-1" type="application/json" url="https://www.dropbox.com/s/0sj2hldpghd7e95/swipeCell.zip?dl=0"/><itunes:explicit/><itunes:subtitle>Here is what we're going to accomplish: (May take a while to show: 3.3MB O_O) But first... digressing (as always) AW YISSS! Be The Bird - Happy With Breadcrumbs XD Hey guys what's going on. Been a while since I last wrote any tutorial for you wonderful programmers. So today I found some time to write it. Something broke in my blog - the source code part doesn't appear as they should! I apologize but as I checked the code formatting widget sourcecode that was hosted on googledrive was removed by the owner! (WTF dude). Anyhow, I needed to change my blog layout design too - as you can see now my blog theme has changed. Many things on the blog didn't work well. For example, you need to open a blog post first before you can read/post comments and so on. So after hours of searching I found an okay-ish blog theme from the blogger standard themes. I feel simplest theme is the best. I still need to find a replacement for the code formatting widget tho. T_T Today I want to teach you how to make your UITableView cells swipeable. In iOS7 (or was it iOS8?), Apple introduce a new API to create swipeable tableview cells. But only limited to buttons (or "actions" as they call it). What if you want to have an image there? Well, if you want images, you still can assign image as the button's backgroundImage. But, what if you want a Switch there? Or TextView? Or thingamabob? (I love this word - THINGAMABOB). The only way to achieve that at the moment, is to CUSTOM CLASS the UITableViewCell. OR!!! OR YOU COULD USE LIBRARY! Yep, there are multiple awesome libraries for swipeable tableview cells created by awesome, generous, developers out there over at GITHUB and other places. However, if you use library, you will not learn so much. This is why I prefer to do things my own, because I want to learn how it works. And you learn best, by doing. So lets go. First, create a single view application. Then you add a UITableView and set all the necessary constraints (sides and bottom to superview margin=0, and top margin to Top Layout guide). Then add a Prototype UITableViewCell on it. This is the cell that we're going to subclass. 1. HOW TO SUBCLASS OBJECT? If you don't know how to subclass an iOS object, tough luck! HAHAHAH! Ok jk, I will teach you here. It is quite an easy task. First, you decide what is the object that you want to subclass (ie customize)? Here, we are going to subclass UITableviewCell. So, Go to XCode and right click at your Project Navigator and select New File... then select "Cocoa Touch Class" under the iOS group. Then click Next.&amp;nbsp; Then, in Subclass drop down menu, select UITableViewCell. Give a name of your new class - "SwipeTableViewCell". As you can see from the drop down menu, all iOS objects are listed here. You can subclass anything from here. Make sure you uncheck the "Also create XIB". We won't be needing a XIB since we already have the object in our storyboard. Click Next and a dialog window will show requiring you to specify location to add the new class. Just click Create and then you will find 2 .m and .h files added to your project. The next step is Critical - assigning your tableviewcell in the storyboard to your newly created class: Observe the arrows. First, select your tableviewcell by clicking on the left panel (don't click on the storyboard object, because sometimes it will select tableview or the contentview instead). Then goto Identity Inspector on the right side panel, and enter your class name here. It should auto-complete by itself (if it doesn't autocomplete, it means you did not select a UITableViewCell object). And... that is all there is to it! You are done subclassing a UITableViewCell!&amp;nbsp; 2. HOW TO CUSTOMIZE THE UITABLEVIEWCELL If you already know how to subclass a tableviewcell, you may skip this section and go to section 3 below. Now, lets customize this cell. As of now, all you did was subclass it but it is still the same old tableview. You need to add objects and codes to modify/customize the cell now. The basic uitableview cell provided by apple already can display items, but it is limited to a few texts - depending on the style of cell that we created. By default, it is "Custom" (and you need to subclass tableviewcell). But if you don't want to subclass the cell, you can still use the default cell XCode provided - you can use Basic (where there is one default label in it), or Subtitle (where there are 2 labels in it). But these styles are fixed. You can't add images to the cell. Or other objects. Now, lets make a decision - what to put in our table. For simplicity sake, lets create a fixed data system that resides in the app bundle (hence is read-only). I created a small database in database.plist file in the following format: [ { Brand = "Honda" Model = "Fit" Price = "$10,000" Specs = "......" } ... ] [ ] denotes array. and { } denotes dictionary. I added 5 entries with various car types. And then I search for these car images and change their name to match their Model (the "Model" field in the data above), and added them to the project's Images.xcasset. The purpose is so that we can load the image with command like: [UIImage imageNamed:[NSString stringWithFormat:@"%@.jpeg",[carDictionary objectForKey:@"Model"]]]; The plan is this: Display photo of car in each cells, with brand and model and price. And then user can swipe the cell to left side to reveal the car specs. First, lets add the necessary objects in our customcell and create all the necessary constraints (Yes! all objects need constraints even inside a tableview cell!). Then connect them to IBOutlets in our customcell header file. Now to load our database into the tableviewcell, we need to tell the Viewcontroller that our table is using it to load data. So lets do that - select our tableview and connect the delegate and datasource to our viewcontroller. We also connect tableview to a local property carTable so we can access it easily. Now, lets create datasource for this table. A datasource is typically a NSMutableArray. NSMutableArray is synonym with tableview because both have indexes. Indexes are important because that is how data is ordered and arranged. Declare a NSMutableArray *carDataArr and lets code loading our local database into this array. NSString *filePath = [[NSBundle mainBundle] pathForResource:@"database" ofType:@"plist"]; carDataArr = [[NSMutableArray alloc] initWithContentsOfFile:filePath]; Next, we need to implement the tableView delegates so we can return this carDataArr as the table's datasource. -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row % 2==0) { cell.contentView.backgroundColor = [UIColor colorWithHue:0 saturation:0 brightness:1.0 alpha:1]; } else { cell.contentView.backgroundColor = [UIColor colorWithHue:0 saturation:0 brightness:0.9 alpha:1]; } } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [carDataArr count]; } -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { SwipeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"swipeCellID"]; if (cell==nil) { cell = [[SwipeTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"swipeCellID"]; } NSDictionary *eachCarData = [carDataArr objectAtIndex:indexPath.row]; cell.carBrand.text = [eachCarData objectForKey:@"Brand"]; cell.carModel.text = [eachCarData objectForKey:@"Model"]; cell.carPrice.text = [eachCarData objectForKey:@"Price"]; cell.carPic.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.jpeg",[eachCarData objectForKey:@"Model"]]]; return cell; } And take a look at what we've accomplished so far! Now we have all the data nicely displayed in the table. Congratulations! :D But wait, we have one more data to display: The car specs! As the tutorial intended: we need to make the cell swipable to left side and display the car spec behind the cell. 3. SWIPEABLE CELL! To visualize how to make a cell swipable, take a look at the following diagram. In a UITableview (grey outline), there are many cells (blue outline) which conforms to its prototype. Inside each cells, there is a contentView (orange rectangle). What we can do is add subviews (green rectangle) behind this contentview and move the contentview to any direction and thus revealing the subview below it. To achieve as the diagram, we need to add some codes to our custom cell class - SwipeTableViewCell.m/.h. Inside the awakeFromNib, enter the following codes: (read the comments to understand what each portion does). - (void)awakeFromNib { [super awakeFromNib]; // Initialization code CGRect containerFrame = self.contentView.frame; // create the textview and add to the contentview of the cell if (self.carSpecs==nil) self.carSpecs = [[UITextView alloc] initWithFrame:CGRectMake(containerFrame.size.width/2.0, containerFrame.origin.y, containerFrame.size.width/2.0, containerFrame.size.height)]; [self.carSpecs setBackgroundColor:[UIColor clearColor]]; [self setBackgroundColor:[UIColor colorWithRed:0.50 green:0.50 blue:0.50 alpha:1.00]]; [self addSubview:self.carSpecs]; [self sendSubviewToBack:self.carSpecs]; // add the shadow to contentview to make it nicer self.contentView.layer.shadowColor = [[UIColor blackColor] CGColor]; self.contentView.layer.shadowRadius = 5.0; self.contentView.layer.shadowOpacity = 1.0; self.contentView.layer.masksToBounds = NO; // CGFloat variable to track our cell movements _oriX = self.contentView.center.x; _xOffset = self.contentView.center.x; // gesture recognizer to detect "swipe" which is actually panning UIPanGestureRecognizer *panLeft = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panLeftHandler:)]; panLeft.delegate = self; self.gestureRecognizers = @[panLeft]; } And then, we need to implement the gesture handler (ie what happens when user swipe our cell). Remember to add &amp;lt;UIGestureRecognizerDelegate&amp;gt; at SwipeTableViewCell.h. Then implement these 2 gesture recognizer delegate methods: (Again, read the comments to see what the code does) - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer { _oriX = _xOffset; // reset the starting location of cell return YES; } -(void)panLeftHandler:(UIPanGestureRecognizer*)panGesture { UIView *cell = [panGesture view]; CGPoint translation = [panGesture translationInView:[cell superview]]; // this is called when user lift finger from screen if ([panGesture state]==UIGestureRecognizerStateEnded) { if (_xOffset&amp;lt;self.frame.size.width/4.0) { // if offset is below treshold, move cell to "open" open [UIView animateWithDuration:0.35 animations:^(void) { self.contentView.center = CGPointMake(0, self.contentView.center.y); }completion:^(BOOL finished) { _xOffset = self.contentView.center.x; }]; } else { // if offset is above treshold, move cell to "close" position [UIView animateWithDuration:0.35 animations:^(void) { self.contentView.center = CGPointMake(self.center.x, self.contentView.center.y); }completion:^(BOOL finished) { _xOffset = self.contentView.center.x; }]; } // the following is called when user keeps on panning finger on the cell } else { // the 50 pixels buffer is to prevent accidental swipes during tableview scrolling if ((translation.x&amp;gt;50)) { // here we update the offset and move the cell's contentview following user's finger _xOffset = _oriX+translation.x-50; self.contentView.center = CGPointMake(_xOffset, self.contentView.center.y); } if ((translation.x&amp;lt;-50)) { // here we update the offset and move the cell's contentview following user's finger _xOffset = _oriX+translation.x+50; self.contentView.center = CGPointMake(_xOffset, self.contentView.center.y); } } } Finally, go back to our ViewController and now we can populate our "Specs" data into the carSpecs UITextView. Add the following line to the cellForRow delegate of our table. cell.carSpecs.text = [eachCarData objectForKey:@"Specs"]; And that's all there is to it. You can replace the UITextView with ANY KIND OF OBJECT as you like. Just be sure to create them programatically properly. You can put multiple objects too, and objects like UISwitch, UIImageView, heck even a ContainerView.</itunes:subtitle><itunes:author>noreply@blogger.com (GeneCode)</itunes:author><itunes:summary>Here is what we're going to accomplish: (May take a while to show: 3.3MB O_O) But first... digressing (as always) AW YISSS! Be The Bird - Happy With Breadcrumbs XD Hey guys what's going on. Been a while since I last wrote any tutorial for you wonderful programmers. So today I found some time to write it. Something broke in my blog - the source code part doesn't appear as they should! I apologize but as I checked the code formatting widget sourcecode that was hosted on googledrive was removed by the owner! (WTF dude). Anyhow, I needed to change my blog layout design too - as you can see now my blog theme has changed. Many things on the blog didn't work well. For example, you need to open a blog post first before you can read/post comments and so on. So after hours of searching I found an okay-ish blog theme from the blogger standard themes. I feel simplest theme is the best. I still need to find a replacement for the code formatting widget tho. T_T Today I want to teach you how to make your UITableView cells swipeable. In iOS7 (or was it iOS8?), Apple introduce a new API to create swipeable tableview cells. But only limited to buttons (or "actions" as they call it). What if you want to have an image there? Well, if you want images, you still can assign image as the button's backgroundImage. But, what if you want a Switch there? Or TextView? Or thingamabob? (I love this word - THINGAMABOB). The only way to achieve that at the moment, is to CUSTOM CLASS the UITableViewCell. OR!!! OR YOU COULD USE LIBRARY! Yep, there are multiple awesome libraries for swipeable tableview cells created by awesome, generous, developers out there over at GITHUB and other places. However, if you use library, you will not learn so much. This is why I prefer to do things my own, because I want to learn how it works. And you learn best, by doing. So lets go. First, create a single view application. Then you add a UITableView and set all the necessary constraints (sides and bottom to superview margin=0, and top margin to Top Layout guide). Then add a Prototype UITableViewCell on it. This is the cell that we're going to subclass. 1. HOW TO SUBCLASS OBJECT? If you don't know how to subclass an iOS object, tough luck! HAHAHAH! Ok jk, I will teach you here. It is quite an easy task. First, you decide what is the object that you want to subclass (ie customize)? Here, we are going to subclass UITableviewCell. So, Go to XCode and right click at your Project Navigator and select New File... then select "Cocoa Touch Class" under the iOS group. Then click Next.&amp;nbsp; Then, in Subclass drop down menu, select UITableViewCell. Give a name of your new class - "SwipeTableViewCell". As you can see from the drop down menu, all iOS objects are listed here. You can subclass anything from here. Make sure you uncheck the "Also create XIB". We won't be needing a XIB since we already have the object in our storyboard. Click Next and a dialog window will show requiring you to specify location to add the new class. Just click Create and then you will find 2 .m and .h files added to your project. The next step is Critical - assigning your tableviewcell in the storyboard to your newly created class: Observe the arrows. First, select your tableviewcell by clicking on the left panel (don't click on the storyboard object, because sometimes it will select tableview or the contentview instead). Then goto Identity Inspector on the right side panel, and enter your class name here. It should auto-complete by itself (if it doesn't autocomplete, it means you did not select a UITableViewCell object). And... that is all there is to it! You are done subclassing a UITableViewCell!&amp;nbsp; 2. HOW TO CUSTOMIZE THE UITABLEVIEWCELL If you already know how to subclass a tableviewcell, you may skip this section and go to section 3 below. Now, lets customize this cell. As of now, all you did was subclass it but it is still the same old tableview. You need to add objects and codes to modify/customize the cell now. The basic uitableview cell provided by apple already can display items, but it is limited to a few texts - depending on the style of cell that we created. By default, it is "Custom" (and you need to subclass tableviewcell). But if you don't want to subclass the cell, you can still use the default cell XCode provided - you can use Basic (where there is one default label in it), or Subtitle (where there are 2 labels in it). But these styles are fixed. You can't add images to the cell. Or other objects. Now, lets make a decision - what to put in our table. For simplicity sake, lets create a fixed data system that resides in the app bundle (hence is read-only). I created a small database in database.plist file in the following format: [ { Brand = "Honda" Model = "Fit" Price = "$10,000" Specs = "......" } ... ] [ ] denotes array. and { } denotes dictionary. I added 5 entries with various car types. And then I search for these car images and change their name to match their Model (the "Model" field in the data above), and added them to the project's Images.xcasset. The purpose is so that we can load the image with command like: [UIImage imageNamed:[NSString stringWithFormat:@"%@.jpeg",[carDictionary objectForKey:@"Model"]]]; The plan is this: Display photo of car in each cells, with brand and model and price. And then user can swipe the cell to left side to reveal the car specs. First, lets add the necessary objects in our customcell and create all the necessary constraints (Yes! all objects need constraints even inside a tableview cell!). Then connect them to IBOutlets in our customcell header file. Now to load our database into the tableviewcell, we need to tell the Viewcontroller that our table is using it to load data. So lets do that - select our tableview and connect the delegate and datasource to our viewcontroller. We also connect tableview to a local property carTable so we can access it easily. Now, lets create datasource for this table. A datasource is typically a NSMutableArray. NSMutableArray is synonym with tableview because both have indexes. Indexes are important because that is how data is ordered and arranged. Declare a NSMutableArray *carDataArr and lets code loading our local database into this array. NSString *filePath = [[NSBundle mainBundle] pathForResource:@"database" ofType:@"plist"]; carDataArr = [[NSMutableArray alloc] initWithContentsOfFile:filePath]; Next, we need to implement the tableView delegates so we can return this carDataArr as the table's datasource. -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row % 2==0) { cell.contentView.backgroundColor = [UIColor colorWithHue:0 saturation:0 brightness:1.0 alpha:1]; } else { cell.contentView.backgroundColor = [UIColor colorWithHue:0 saturation:0 brightness:0.9 alpha:1]; } } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [carDataArr count]; } -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { SwipeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"swipeCellID"]; if (cell==nil) { cell = [[SwipeTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"swipeCellID"]; } NSDictionary *eachCarData = [carDataArr objectAtIndex:indexPath.row]; cell.carBrand.text = [eachCarData objectForKey:@"Brand"]; cell.carModel.text = [eachCarData objectForKey:@"Model"]; cell.carPrice.text = [eachCarData objectForKey:@"Price"]; cell.carPic.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.jpeg",[eachCarData objectForKey:@"Model"]]]; return cell; } And take a look at what we've accomplished so far! Now we have all the data nicely displayed in the table. Congratulations! :D But wait, we have one more data to display: The car specs! As the tutorial intended: we need to make the cell swipable to left side and display the car spec behind the cell. 3. SWIPEABLE CELL! To visualize how to make a cell swipable, take a look at the following diagram. In a UITableview (grey outline), there are many cells (blue outline) which conforms to its prototype. Inside each cells, there is a contentView (orange rectangle). What we can do is add subviews (green rectangle) behind this contentview and move the contentview to any direction and thus revealing the subview below it. To achieve as the diagram, we need to add some codes to our custom cell class - SwipeTableViewCell.m/.h. Inside the awakeFromNib, enter the following codes: (read the comments to understand what each portion does). - (void)awakeFromNib { [super awakeFromNib]; // Initialization code CGRect containerFrame = self.contentView.frame; // create the textview and add to the contentview of the cell if (self.carSpecs==nil) self.carSpecs = [[UITextView alloc] initWithFrame:CGRectMake(containerFrame.size.width/2.0, containerFrame.origin.y, containerFrame.size.width/2.0, containerFrame.size.height)]; [self.carSpecs setBackgroundColor:[UIColor clearColor]]; [self setBackgroundColor:[UIColor colorWithRed:0.50 green:0.50 blue:0.50 alpha:1.00]]; [self addSubview:self.carSpecs]; [self sendSubviewToBack:self.carSpecs]; // add the shadow to contentview to make it nicer self.contentView.layer.shadowColor = [[UIColor blackColor] CGColor]; self.contentView.layer.shadowRadius = 5.0; self.contentView.layer.shadowOpacity = 1.0; self.contentView.layer.masksToBounds = NO; // CGFloat variable to track our cell movements _oriX = self.contentView.center.x; _xOffset = self.contentView.center.x; // gesture recognizer to detect "swipe" which is actually panning UIPanGestureRecognizer *panLeft = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panLeftHandler:)]; panLeft.delegate = self; self.gestureRecognizers = @[panLeft]; } And then, we need to implement the gesture handler (ie what happens when user swipe our cell). Remember to add &amp;lt;UIGestureRecognizerDelegate&amp;gt; at SwipeTableViewCell.h. Then implement these 2 gesture recognizer delegate methods: (Again, read the comments to see what the code does) - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer { _oriX = _xOffset; // reset the starting location of cell return YES; } -(void)panLeftHandler:(UIPanGestureRecognizer*)panGesture { UIView *cell = [panGesture view]; CGPoint translation = [panGesture translationInView:[cell superview]]; // this is called when user lift finger from screen if ([panGesture state]==UIGestureRecognizerStateEnded) { if (_xOffset&amp;lt;self.frame.size.width/4.0) { // if offset is below treshold, move cell to "open" open [UIView animateWithDuration:0.35 animations:^(void) { self.contentView.center = CGPointMake(0, self.contentView.center.y); }completion:^(BOOL finished) { _xOffset = self.contentView.center.x; }]; } else { // if offset is above treshold, move cell to "close" position [UIView animateWithDuration:0.35 animations:^(void) { self.contentView.center = CGPointMake(self.center.x, self.contentView.center.y); }completion:^(BOOL finished) { _xOffset = self.contentView.center.x; }]; } // the following is called when user keeps on panning finger on the cell } else { // the 50 pixels buffer is to prevent accidental swipes during tableview scrolling if ((translation.x&amp;gt;50)) { // here we update the offset and move the cell's contentview following user's finger _xOffset = _oriX+translation.x-50; self.contentView.center = CGPointMake(_xOffset, self.contentView.center.y); } if ((translation.x&amp;lt;-50)) { // here we update the offset and move the cell's contentview following user's finger _xOffset = _oriX+translation.x+50; self.contentView.center = CGPointMake(_xOffset, self.contentView.center.y); } } } Finally, go back to our ViewController and now we can populate our "Specs" data into the carSpecs UITextView. Add the following line to the cellForRow delegate of our table. cell.carSpecs.text = [eachCarData objectForKey:@"Specs"]; And that's all there is to it. You can replace the UITextView with ANY KIND OF OBJECT as you like. Just be sure to create them programatically properly. You can put multiple objects too, and objects like UISwitch, UIImageView, heck even a ContainerView.</itunes:summary><itunes:keywords>cell, custom, object, swipe, swipeable, tableview, uitableviewcell</itunes:keywords></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-6469637844039484058</guid><pubDate>Tue, 17 May 2016 07:38:00 +0000</pubDate><atom:updated>2016-09-20T19:47:53.734-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">7</category><category domain="http://www.blogger.com/atom/ns#">between</category><category domain="http://www.blogger.com/atom/ns#">files</category><category domain="http://www.blogger.com/atom/ns#">lag</category><category domain="http://www.blogger.com/atom/ns#">solution</category><category domain="http://www.blogger.com/atom/ns#">switching</category><category domain="http://www.blogger.com/atom/ns#">viewcontrollers</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><title>How To: Fix XCode 7 Lag</title><description>Hello darlings. This is not a coding tutorial but related to XCode so I post here.&lt;br /&gt;
&lt;br /&gt;
XCode lag when switching between files?&lt;br /&gt;
&lt;br /&gt;
I am using XCode 7.2.1 and Yosemite, and suddenly XCode lags when trying to switch between ViewControllers. I have tried many solutions suggested in internet:&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
1. Clear Derived Data&lt;br /&gt;
2. Clear Archives&lt;br /&gt;
3. Disable Spotlight Indexing&lt;br /&gt;
&lt;br /&gt;
These somewhat make XCode works faster when building apps, but lags is still there when Im switching btw viewcontroller and/or xib files.&lt;br /&gt;
&lt;br /&gt;
The lag also happens intermittently. Which makes it hard to figure out what's causing the problem. Then I searched further and found some people talking about TOOLTIPS in Apple Forum.&lt;br /&gt;
&lt;br /&gt;
It seems to be the root cause. If you have files with long filenames (such as below):&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxyZsf6AlWQ1YQkUI4_g_Un2EK_Kzx3HyXri6cQS9kPpNLfKt9CSw1dBhNfUkKvAALVdT-1EmJXpDCtMRh37upYi8mrtVw4utsTy9b2zJWVGcYi6T3qcXTE26LNXVD_5vp1Vj3k5UwkuU/s1600/tooltip.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxyZsf6AlWQ1YQkUI4_g_Un2EK_Kzx3HyXri6cQS9kPpNLfKt9CSw1dBhNfUkKvAALVdT-1EmJXpDCtMRh37upYi8mrtVw4utsTy9b2zJWVGcYi6T3qcXTE26LNXVD_5vp1Vj3k5UwkuU/s1600/tooltip.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Everytime your mouse hovers those truncated filenames, XCode tries to show tooltip for it, and that's when the lag happens.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
What you do? Just WIDEN THE LEFT PANE. This seems to work for me. Do note though- after you widen it, and then you narrow it back, it becomes totally ok only after a while, it lags again. Just leave the pane widened till there is no "..." in the file names and you'd be okay all the way.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
This is really funny problem I hope XCode devs team fix it soon.&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;</description><link>http://xcodenoobies.blogspot.com/2016/05/how-to-fix-xcode-7-lag_17.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxyZsf6AlWQ1YQkUI4_g_Un2EK_Kzx3HyXri6cQS9kPpNLfKt9CSw1dBhNfUkKvAALVdT-1EmJXpDCtMRh37upYi8mrtVw4utsTy9b2zJWVGcYi6T3qcXTE26LNXVD_5vp1Vj3k5UwkuU/s72-c/tooltip.png" width="72"/><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-43173623428510107</guid><pubDate>Wed, 13 Jan 2016 07:08:00 +0000</pubDate><atom:updated>2016-11-19T00:31:18.081-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">animation</category><category domain="http://www.blogger.com/atom/ns#">gif</category><category domain="http://www.blogger.com/atom/ns#">jpg</category><category domain="http://www.blogger.com/atom/ns#">mov</category><category domain="http://www.blogger.com/atom/ns#">movie</category><category domain="http://www.blogger.com/atom/ns#">mp4</category><category domain="http://www.blogger.com/atom/ns#">png</category><category domain="http://www.blogger.com/atom/ns#">slrequest</category><category domain="http://www.blogger.com/atom/ns#">twitter</category><category domain="http://www.blogger.com/atom/ns#">upload</category><title>How To: Using SLRequest to Upload Image or Video To Twitter</title><description>Hi guys what's up. This is a simple tutorial so it doesn't have any downloadable project.&lt;br /&gt;
&lt;br /&gt;
Today I'd like to share with you how to upload an image (like JPEG or GIF animation) to Twitter from the iOS app.&lt;br /&gt;
&lt;br /&gt;
For a normal JPEG and status upload, you can use SLComposeViewController but you will face problem if you want to upload GIF animation or video file. That is because SLComposeViewController only has "addImage" method that takes up a UIImage object.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
So you have to use SLRequest - a low level API communicator.&lt;br /&gt;
&lt;br /&gt;
There was a simple API request called "upload_with_media" but Twitter has DEPRECATED it. It works now, but it may not work anymore in the near future and thus may break your app if you use that. So now you need to use 2 APIs to tweet text and image in one tweet. The processes involved is basically 2 - tiered jobs:&lt;br /&gt;
&lt;br /&gt;
1. Upload image first - you will get the media id after upload completes&lt;br /&gt;
2. Update status with text and the media ID&lt;br /&gt;
&lt;br /&gt;
As usual you have to request access to Twitter account before you can do anything with it. Once access is granted by user, you can then proceed to instantiate requests to twitter API host. Here's how to upload a media to Twitter's Media server:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

NSData *imageData = [NSData dataWithContentsOfURL:fileURL];
NSURL *requestURL = [NSURL URLWithString:@"https://upload.twitter.com/1.1/media/upload.json"];
                    
SLRequest *postRequest = [SLRequest 
                                              requestForServiceType:SLServiceTypeTwitter
                                              requestMethod:SLRequestMethodPOST
                                              URL:requestURL parameters:nil;
                    
postRequest.account = twitterAccount;
[postRequest addMultipartData:imageData
                                         withName:@"media"
                                             type:@"image/gif"
                                         filename:@"test.gif"];
                    
[postRequest performRequestWithHandler:^(NSData *responseData,
                                                 NSHTTPURLResponse *urlResponse, NSError *error)
                     {
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
First, convert your image/video into NSData. Then create an SLRequest with NIL PARAMETERS with POST method as in code above. Set the request's account. Then add multipart data to the request.&lt;br /&gt;
&lt;br /&gt;
The data type must be matching to what you're uploading. If it's a JPG then use "image/jpeg" if it's a GIF then use "image/gif" etc. Finally perform the request to start uploading the image to twitter's media server. This may take a while so you should have a UIActivityViewController pop up when doing this.&lt;br /&gt;
&lt;br /&gt;
When the request is completed, the method will return responseData in JSON format. Convert this data into JSON.&lt;br /&gt;
&lt;br /&gt;
Example of JSON data returned from twitter:
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
{
    "expires_after_secs" = 86400;
    image =     {
        h = 400;
        "image_type" = "image/gif";
        w = 400;
    };
    "media_id" = 687171095254859776;
    "media_id_string" = 687171095254859776; ---- THIS IS WHAT YOU NEED
    size = 705439;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Retrieve the media ID string as follows:
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
NSString *mediaID = [json objectForKey:@"media_id_string"];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Once you get the mediaID, you can then tweet a text with this ID using /statuses/update.json API.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt; 
NSURL *requestURL2 = [NSURL URLWithString:@"https://api.twitter.com/1.1/statuses/update.json"];
NSDictionary *message2 = @{@"status": @"Here is image",
                                                    @"media_ids": mediaID };
                         
SLRequest *postRequest2 = [SLRequest
                                                   requestForServiceType:SLServiceTypeTwitter
                                                   requestMethod:SLRequestMethodPOST
                                                   URL:requestURL2 parameters:message2];
postRequest2.account = twitterAccount;
                         
[postRequest2 performRequestWithHandler:^(NSData *responseData,
                                                      NSHTTPURLResponse *urlResponse, NSError *error)
                          {
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The second request is just the same method performRequestWithHandler but with different requestURL. And that's how it's done.&lt;br /&gt;
&lt;br /&gt;
Here is the complete code (including requesting access to twitter account):&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

-(void)uploadImageToTwitter {


        
        ACAccountStore *account = [[ACAccountStore alloc] init];
        ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:
                                      ACAccountTypeIdentifierTwitter];
        
        [account requestAccessToAccountsWithType:accountType options:nil
                                      completion:^(BOOL granted, NSError *error)
        {
            if (granted == YES)
            {
                NSArray *arrayOfAccounts = [account
                                            accountsWithAccountType:accountType];
                
                if ([arrayOfAccounts count] &amp;gt; 0)
                {
                    ACAccount *twitterAccount =
                    [arrayOfAccounts lastObject];
                    
                    
                    NSURL *furl = [NSURL fileURLWithPath:NSTemporaryDirectory()];
                    NSURL *fileURL = [furl URLByAppendingPathComponent:@"animation.gif"];
                    NSData *imageData = [NSData dataWithContentsOfURL:fileURL];
                   
                    NSURL *requestURL = [NSURL URLWithString:@"https://upload.twitter.com/1.1/media/upload.json"];
                    
                    SLRequest *postRequest = [SLRequest 
                                              requestForServiceType:SLServiceTypeTwitter
                                              requestMethod:SLRequestMethodPOST
                                              URL:requestURL parameters:nil];
                    
                    postRequest.account = twitterAccount;
                    
                    [postRequest addMultipartData:imageData
                                         withName:@"media"
                                             type:@"image/gif"
                                         filename:@"test.gif"];
                    
                    [postRequest
                     performRequestWithHandler:^(NSData *responseData,
                                                 NSHTTPURLResponse *urlResponse, NSError *error)
                     {
                         
                         
                          NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
                         
                         NSString *mediaID = [json objectForKey:@"media_id_string"];
                         
                         
                         if (mediaID!=nil) {
                             
                         
                             NSURL *requestURL2 = [NSURL URLWithString:@"https://api.twitter.com/1.1/statuses/update.json"];
                         NSDictionary *message2 = @{@"status": @"Here is the image",
                                                    @"media_ids": mediaID };
                         
                         SLRequest *postRequest2 = [SLRequest
                                                   requestForServiceType:SLServiceTypeTwitter
                                                   requestMethod:SLRequestMethodPOST
                                                   URL:requestURL2 parameters:message2];
                         postRequest2.account = twitterAccount;
                         
                         [postRequest2
                          performRequestWithHandler:^(NSData *responseData,
                                                      NSHTTPURLResponse *urlResponse, NSError *error)
                          {
                             // DONE!!!

                          }];
                             
                         }
                         
                     }];
                }
            }
         }];

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
That's all FOLKS!</description><link>http://xcodenoobies.blogspot.com/2016/01/how-to-using-slrequest-to-upload-image.html</link><author>noreply@blogger.com (GeneCode)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-9155076576439399967</guid><pubDate>Thu, 19 Nov 2015 07:17:00 +0000</pubDate><atom:updated>2016-12-13T21:00:15.166-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">example</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">map</category><category domain="http://www.blogger.com/atom/ns#">MKMApview</category><category domain="http://www.blogger.com/atom/ns#">MKTileOverlay</category><category domain="http://www.blogger.com/atom/ns#">overlay</category><category domain="http://www.blogger.com/atom/ns#">pre</category><category domain="http://www.blogger.com/atom/ns#">process</category><category domain="http://www.blogger.com/atom/ns#">tile</category><category domain="http://www.blogger.com/atom/ns#">tutorial</category><title>How To: Pre-Process Tilemap Overlays in MKMapView</title><description>Hi all.&lt;br /&gt;
&lt;br /&gt;
Time for another tutorial. Recently I was trying to modify a tilemap returned from a typical public map overlay server (such as openstreetmap.org) - basically I needed a way to change black areas of the tile into transparent so that I could nicely overlay it on top of MKMapView. I searched for this for a while, found some solutions but did not really work as I wanted. Some examples used MKTileOverlayRenderer. Somehow that gave me weird results that I do not understand.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
Note: In this tutorial there are no downloadable project since it is a straight forward MKTileOverlay subclassing usage. (But, if u really need a sample project, do shout in the comment section).&lt;/blockquote&gt;
&lt;br /&gt;
In your custom MKTileOverlay, you return the URL to load according to map rect using the normal URLForTilePath as usual. Then in the loadTileAtPath method, you process the *data variable.&lt;br /&gt;
&lt;br /&gt;
Here is the example of the method:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;
- (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *, NSError *))result
{
    if (!result)
    {
        return;
    }
   
        NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            
            if ([data length]&amp;lt;335) {
                
                result(nil,nil);
            } else {
                
                    CGSize sz = CGSizeMake(256,256);
                    CGRect rect = CGRectMake(0,0,256,256);
                    UIImage *img = [UIImage imageWithData:data];
                    
                    UIGraphicsBeginImageContext(sz);
                    CGContextRef context = UIGraphicsGetCurrentContext();
                    
                    [img drawInRect:rect];
                    
                    UInt8 *dat = CGBitmapContextGetData(context);
                    // int numComponents = 4;
                    long dataLength = CGBitmapContextGetHeight(context) * CGBitmapContextGetBytesPerRow(context);
                    
                    int  Comp1, Comp2, Comp3, Comp4;
                    
                    Comp1 = 0;
                    Comp2 = 1;
                    Comp3 = 2;
                    Comp4 = 3;

                    // This processes each pixels and convert the map to greyscale.

                    for(int index=0;index&amp;lt;dataLength;index+=4){
                        int aRed = dat[index+Comp1];
                        int aGrn = dat[index+Comp2];
                        int aBlu = dat[index+Comp3];
                        
                        float grey = (aRed+aGrn+aBlu)/3.0;
                        
                        dat[index+Comp1] = grey;
                         dat[index+Comp2] = grey;
                         dat[index+Comp3] = grey;
                        
                    }
                    
                    UIImage *tileImage = UIGraphicsGetImageFromCurrentImageContext();
                    UIGraphicsEndImageContext();
                    NSData *tileData = UIImagePNGRepresentation(tileImage);
                    result(tileData,nil); // return new data


                  
            }
        }];

}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
As in the method above: Take *data and convert it to UIImage. Create a graphic context to draw on. Draw the map on that context. Then further manipulate the context pixels by pixels. Finally get the resulting image from the modified context and return as result.&lt;br /&gt;
&lt;br /&gt;
Normal original openstreetmap tile (unmodified) loaded unto MKMapView as MKTileOverlay:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCg3sCJoMGQriF9y9fTR0TzXUP_hRzydeOGXEK5MRJbCuFi3aemSKOD1eoL9L8mSUAjD9I1b4N7StiweZjipHAVKtrOoGkrEXmrTfVbNwnqJi1JHf-Z6DI4aoXww0KZexsZp7t_AYMgy8/s1600/Simulator+Screen+Shot+Nov+19%252C+2015%252C+3.08.35+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="319" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCg3sCJoMGQriF9y9fTR0TzXUP_hRzydeOGXEK5MRJbCuFi3aemSKOD1eoL9L8mSUAjD9I1b4N7StiweZjipHAVKtrOoGkrEXmrTfVbNwnqJi1JHf-Z6DI4aoXww0KZexsZp7t_AYMgy8/s320/Simulator+Screen+Shot+Nov+19%252C+2015%252C+3.08.35+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Change to grey (pixels to grey code given in the method above):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiu80jgpcUZmhMpd4IEYgQc5tsUa09RVPy8JtU6T4rMbbbCxCtKIgqHLA9H5QBTT6izCcRYU9WrySOYLZ0A6PdtnmN3rVL-4HcjAiIyvotHTcDvrde6CXV505_YwaXv9rqfKJpKApA7l4/s1600/Simulator+Screen+Shot+Nov+19%252C+2015%252C+2.59.53+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiu80jgpcUZmhMpd4IEYgQc5tsUa09RVPy8JtU6T4rMbbbCxCtKIgqHLA9H5QBTT6izCcRYU9WrySOYLZ0A6PdtnmN3rVL-4HcjAiIyvotHTcDvrde6CXV505_YwaXv9rqfKJpKApA7l4/s320/Simulator+Screen+Shot+Nov+19%252C+2015%252C+2.59.53+PM.png" width="315" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Change to invert color:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8u0HgKtaRT58GpHbtRqCdSaR2yLOcaY-DyR7G8Es4gYl2XabQPcwos2GxytfKb5eAjL-KyPHG2dcUPTDjGAuIzcKwOu9vsrqNejTq636VORUlaWfQWrNKUeZlGauaI3R22Zea2umJiwQ/s1600/Simulator+Screen+Shot+Nov+19%252C+2015%252C+3.01.05+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="317" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8u0HgKtaRT58GpHbtRqCdSaR2yLOcaY-DyR7G8Es4gYl2XabQPcwos2GxytfKb5eAjL-KyPHG2dcUPTDjGAuIzcKwOu9vsrqNejTq636VORUlaWfQWrNKUeZlGauaI3R22Zea2umJiwQ/s320/Simulator+Screen+Shot+Nov+19%252C+2015%252C+3.01.05+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Change to High Saturation&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlvEPOMYWv3nB7oW21PLQunu81rpbWwZmipPTziob1GO_vAMQ4AViyoej3qVDKIpkvx-1BQacYOAlP0wOif8JDw3MSZzkSyWg4VHtGeg7pyFZMpf1UBE7pJsv75hSp_U5z1wwo_bGMQwo/s1600/Simulator+Screen+Shot+Nov+19%252C+2015%252C+3.07.47+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="319" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlvEPOMYWv3nB7oW21PLQunu81rpbWwZmipPTziob1GO_vAMQ4AViyoej3qVDKIpkvx-1BQacYOAlP0wOif8JDw3MSZzkSyWg4VHtGeg7pyFZMpf1UBE7pJsv75hSp_U5z1wwo_bGMQwo/s320/Simulator+Screen+Shot+Nov+19%252C+2015%252C+3.07.47+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: The air pollution markers are on another MKTileOverlay.&lt;br /&gt;
&lt;br /&gt;
All these 4 map styles came from a single tileserver (openstreetmap.org).&lt;br /&gt;
&lt;br /&gt;
Do take note that each time a tile (of size 256x256) is loaded, your custom class will process it with CoreGraphics with the code given. It is wise to keep the processing simple and not too heavy burden on processor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://xcodenoobies.blogspot.com/2015/11/how-to-pre-process-tilemap-overlays-in.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCg3sCJoMGQriF9y9fTR0TzXUP_hRzydeOGXEK5MRJbCuFi3aemSKOD1eoL9L8mSUAjD9I1b4N7StiweZjipHAVKtrOoGkrEXmrTfVbNwnqJi1JHf-Z6DI4aoXww0KZexsZp7t_AYMgy8/s72-c/Simulator+Screen+Shot+Nov+19%252C+2015%252C+3.08.35+PM.png" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-2400128556939898228</guid><pubDate>Sat, 03 Oct 2015 11:18:00 +0000</pubDate><atom:updated>2016-09-20T21:26:38.007-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">application</category><category domain="http://www.blogger.com/atom/ns#">no</category><category domain="http://www.blogger.com/atom/ns#">only</category><category domain="http://www.blogger.com/atom/ns#">project</category><category domain="http://www.blogger.com/atom/ns#">single</category><category domain="http://www.blogger.com/atom/ns#">storyboard</category><category domain="http://www.blogger.com/atom/ns#">view</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><category domain="http://www.blogger.com/atom/ns#">xib</category><title>LONG LIVE XIBs!!!! Create an iOS app without storyboards in XCode</title><description>Are you one of those devs who don't like Storyboard? I didn't even bother to learn about Storyboards and how to use them. Call me stubborn noob that's ok. But I am so used to programmatically create things on XCode so storyboards are not my thang.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So how do you do this with latest XCode? If you go to New Project LO AND BEHOLD no such thing as a project without storyboards. All of them has storyboards. Unless you go with the absolute empty project.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
What I will show you is how to select a Single View Project and then make it run without Storyboard. Let's go! First go to menu File -- New -- Project... and select Single View Application. Then follow the following steps:&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
1. DELETE THE FRIGGIN STORYBOARD!&lt;/div&gt;
&lt;div&gt;
Well, obviously, first thing to do it is to delete the storyboard!&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmRWcJ-hk25sC4LWZvhKLLodYI-L8tE3hGVG1odz8GsARdKtDSvVMhutH8mNnKgNLAXAvDwQeS3F_WI2smK2G0N6hNAzmn_Z8guS1UVlT3cwiYk2l7tQNdJ4QypwlA2OXnP0-BqpC1qLw/s1600/Screen+Shot+2015-10-03+at+6.53.39+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmRWcJ-hk25sC4LWZvhKLLodYI-L8tE3hGVG1odz8GsARdKtDSvVMhutH8mNnKgNLAXAvDwQeS3F_WI2smK2G0N6hNAzmn_Z8guS1UVlT3cwiYk2l7tQNdJ4QypwlA2OXnP0-BqpC1qLw/s400/Screen+Shot+2015-10-03+at+6.53.39+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
2. Delete the "Main" text in Main Interface under General Tab in the target.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYq_7FgQESzzsKbbRqXPHVpGf1n0XFEOft6EfIjsnG8KdPhsQtpClXo0tS7VnIgG7xru8CQay6PLpNo9Xt-IqThDcq4JlysZmLFcloRrdtXFUPXJ4s_1FJqU5nj8srOpYFenqEK_QUNiE/s1600/Screen+Shot+2015-10-03+at+6.54.13+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYq_7FgQESzzsKbbRqXPHVpGf1n0XFEOft6EfIjsnG8KdPhsQtpClXo0tS7VnIgG7xru8CQay6PLpNo9Xt-IqThDcq4JlysZmLFcloRrdtXFUPXJ4s_1FJqU5nj8srOpYFenqEK_QUNiE/s400/Screen+Shot+2015-10-03+at+6.54.13+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
3. Right click your project in the left panel and select New File... and goto iOS - User interface - View and click Next. Give the xib name "ViewController" (basically same name as your viewcontroller.m and h).&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitNsukKnKHB326gX0qmrbYueZzpjiVn4DaOHMoSyHg5imDcbjE1IkFgeHlzLx4phSLTKZ1laEeS2epCYfQHou1vK4bpfAfUHDwkdT-x6gKo2rPzdC17Kou7hO3Aejh4m6Bq_SO_2dA2OI/s1600/Screen+Shot+2015-10-03+at+6.54.36+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="289" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitNsukKnKHB326gX0qmrbYueZzpjiVn4DaOHMoSyHg5imDcbjE1IkFgeHlzLx4phSLTKZ1laEeS2epCYfQHou1vK4bpfAfUHDwkdT-x6gKo2rPzdC17Kou7hO3Aejh4m6Bq_SO_2dA2OI/s640/Screen+Shot+2015-10-03+at+6.54.36+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
4. Click on your newly created XIB file. Click on the File's Owner (yellow box), then click on the Identity Inspector tab, and type "ViewController" in the Class field. &amp;nbsp;(see the red boxes highlighted in the image below)&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWD6vg8iDX4Kqw4rKBYxXpwPpfUEWNT7qMNEmuz8EhgY-pK6kgbb60RQb66buleWk6Y-ytJn6Pwj0DvxOGkFOLjO7kgLJDc6VzC5FrDcKXDCqlhLqgRK2hKG2G0kAJsuzAeNlaLoJ84E0/s1600/Screen+Shot+2015-10-03+at+6.54.55+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWD6vg8iDX4Kqw4rKBYxXpwPpfUEWNT7qMNEmuz8EhgY-pK6kgbb60RQb66buleWk6Y-ytJn6Pwj0DvxOGkFOLjO7kgLJDc6VzC5FrDcKXDCqlhLqgRK2hKG2G0kAJsuzAeNlaLoJ84E0/s640/Screen+Shot+2015-10-03+at+6.54.55+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
5. Then click on the View part of XIB file and click on the &amp;nbsp;Connections Inspector tab and connect the Referencing Outlet to the File's Owner and select "view".&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJs3E-Yv8GsaG10ZKk2Xuff3J73vRz1sDb1PsNSOhM_Ow2F9hCqeNueTIMoM9A8knc8JNNAX5LTsrFcFYYzc6wkOy_8u3rRNJQNAH2vaD94nb_ViSXjm1lZ8kVWAF_0oylysX0KJtPMXM/s1600/Screen+Shot+2015-10-03+at+6.57.12+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJs3E-Yv8GsaG10ZKk2Xuff3J73vRz1sDb1PsNSOhM_Ow2F9hCqeNueTIMoM9A8knc8JNNAX5LTsrFcFYYzc6wkOy_8u3rRNJQNAH2vaD94nb_ViSXjm1lZ8kVWAF_0oylysX0KJtPMXM/s640/Screen+Shot+2015-10-03+at+6.57.12+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
6. Click your AppDelegate.h, and add these codes:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpOGxFxHiNbnhkrCbA5vZuykVYK-f5DH7BHp_V-Qe_MQy_rQVRFJiejbFIVPYWNLDJ8-UIYGSJe6a5QCfIH8r6Oxo0t93Dy_QSUHQmalxQLYti-RpzehTlVYz1LG4h3Oppq7OBRUdfssY/s1600/Screen+Shot+2015-10-03+at+6.56.06+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="274" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpOGxFxHiNbnhkrCbA5vZuykVYK-f5DH7BHp_V-Qe_MQy_rQVRFJiejbFIVPYWNLDJ8-UIYGSJe6a5QCfIH8r6Oxo0t93Dy_QSUHQmalxQLYti-RpzehTlVYz1LG4h3Oppq7OBRUdfssY/s640/Screen+Shot+2015-10-03+at+6.56.06+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
(see the red box highlights).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
6. Then click on AppDelegate.m and add these codes in the appDidFinishLaunching method:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVnQt3RteCIHaT5QU-htQwAvj2C1RUt2s4Wkh9ArNuuBcuYwNiZH0xOd_uIiUzyU6BDoN3BYfJFxkRPp1uK_sCoMgpBCw_iQHn796J8K1nwv7rREnWkneoNlTO1RWDfGehJ1rWvyq7zCY/s1600/Screen+Shot+2015-10-03+at+6.56.39+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="304" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVnQt3RteCIHaT5QU-htQwAvj2C1RUt2s4Wkh9ArNuuBcuYwNiZH0xOd_uIiUzyU6BDoN3BYfJFxkRPp1uK_sCoMgpBCw_iQHn796J8K1nwv7rREnWkneoNlTO1RWDfGehJ1rWvyq7zCY/s640/Screen+Shot+2015-10-03+at+6.56.39+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
DONE!&lt;/div&gt;
&lt;div&gt;
That's all and you should be able to run the app and it will show an empty white View.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Finally, LONG LIVE XIB!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://xcodenoobies.blogspot.com/2015/10/how-to-create-basic-single-view-project.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmRWcJ-hk25sC4LWZvhKLLodYI-L8tE3hGVG1odz8GsARdKtDSvVMhutH8mNnKgNLAXAvDwQeS3F_WI2smK2G0N6hNAzmn_Z8guS1UVlT3cwiYk2l7tQNdJ4QypwlA2OXnP0-BqpC1qLw/s72-c/Screen+Shot+2015-10-03+at+6.53.39+PM.png" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-7174283021456050185</guid><pubDate>Sun, 27 Sep 2015 08:38:00 +0000</pubDate><atom:updated>2016-11-19T00:34:58.247-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">design</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">levels</category><category domain="http://www.blogger.com/atom/ns#">scroll</category><category domain="http://www.blogger.com/atom/ns#">scrollview</category><category domain="http://www.blogger.com/atom/ns#">selector</category><category domain="http://www.blogger.com/atom/ns#">skspritekit</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><title>SKScrollView: SKSpriteKit ScrollView for Games Levels</title><description>Hey guys how are you doing? Hope you are doing great.&lt;br /&gt;
&lt;br /&gt;
I have a sample project to share. Well, as usual, I wanted to do something and then search around and most of available solution is way too complicated or not to my liking. So I MAKE ONE MYSELF. YAYYYYYYY xD Great way to spend my Sunday evening with a cuppa coffee.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://www.dropbox.com/s/gp6p8f6ekn7pjrn/SKScrollView.zip?dl=0"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwLxvdeV19GlIOwzASKbWSKhUwjBPNy2jxMLuw5rPaWHzsF1SOfJYjf_ENH8wqM3GOdC6-h8S_JLY2sPFMmZDH6-ITjy7jwshUUYhFuWCX9lIbvWoWh1J7s-ychzXOczOj_MzKWlH-hw/s320/download.png" /&gt;&lt;/a&gt;
&lt;br /&gt;
So what I wanted to do is this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOOGjo8c1ducJxJky-Vl1Xv_2DkgNcSl7vuaMedYOeB5F3iwuOprEPkC3XBVAkw7v2SCR8m-g-gKH70_dM81-FGI1RQZ2kc8NmZX3g-xq9akeF8aP-oGXP6F_YXElpWcZDATA1lCpUS7w/s1600/photo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOOGjo8c1ducJxJky-Vl1Xv_2DkgNcSl7vuaMedYOeB5F3iwuOprEPkC3XBVAkw7v2SCR8m-g-gKH70_dM81-FGI1RQZ2kc8NmZX3g-xq9akeF8aP-oGXP6F_YXElpWcZDATA1lCpUS7w/s320/photo.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
If you haven't already noticed, this is a screenshot from the famous game Cut The Rope. Aww come on you should know this everybody loves OM NOM! Look at him:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSlAsVoTEzxLjluSzpOokqoNQD_7-YfX3pWNFX7-zVV_Q6f1wQDR4ymM73oAgjFDAif_NXAYZ3rwZR7f1gwNcoBJSwkZKn0kt-9QQfzdg0id5E2lyrQcD6SfhoI5GoxBB1rD1tHLxr2dE/s1600/Om-nom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSlAsVoTEzxLjluSzpOokqoNQD_7-YfX3pWNFX7-zVV_Q6f1wQDR4ymM73oAgjFDAif_NXAYZ3rwZR7f1gwNcoBJSwkZKn0kt-9QQfzdg0id5E2lyrQcD6SfhoI5GoxBB1rD1tHLxr2dE/s200/Om-nom.png" width="193" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
XD&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Anyway, I wanted to have a scrollview of many worlds and each view has its own number of levels. Most solutions I found basically loads everything (all worlds all levels) into ONE SKScene. Wtf people. Good dev should avoid cramping everything and loading shitload of bytes into one scene.&amp;nbsp;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
So best way to do this is to make a General Scene and loads stuffs based on the world we're currently selecting.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Check out the GIF below (this is what I created and sharing to you all for free :DDDDD)&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqvNwyIUywRKq-rBTCs5clvCJBx9b_R7ZVhlRZZNJFjs_RExGZZ6gQa2jlFePGxBUaZ8YNZkZHD6lHvhpe3f0dc4QdiYZCYPn3wtaOXR6n_gPFNjyAmDWQh_jhktQBIsf9KMH71YUO50A/s1600/skscrollview.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqvNwyIUywRKq-rBTCs5clvCJBx9b_R7ZVhlRZZNJFjs_RExGZZ6gQa2jlFePGxBUaZ8YNZkZHD6lHvhpe3f0dc4QdiYZCYPn3wtaOXR6n_gPFNjyAmDWQh_jhktQBIsf9KMH71YUO50A/s400/skscrollview.gif" width="225" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
(Be patient the GIF is 1.1MB.)&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
There is only one level selector scene file. And the scene calls itself based on which world currently is selected. Total Worlds is defined in the ViewController:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="CSharp" name="code"&gt;  
 // STARTING WORLD AND TOTAL WORLDS SET UP
        NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
        [def setInteger:1 forKey:@"World"];
        [def setInteger:3 forKey:@"TotalWorld"];
        [def synchronize];
&lt;/pre&gt;
&lt;br /&gt;
If you want to have 5 Worlds to the project, please change the "3" to "5". You get the idea right.&lt;br /&gt;
The "World" key is the "Current selected world" variable.&lt;br /&gt;
&lt;br /&gt;
Each world details are crafted inside PLISTs files inside the project - World1.plist for first world, World2.plist for second world, and so on. Each world plist has the following format:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpHpAo3cYqoIv2nfKRFDqyEEuW0OhXO0wkv7cbr8FKXGl74iNaSySMx_iWwkIJrIugmBaXNNoeEpioerxGGAmZA9ECSUn-4zAe-wB-POoueoZiAK9zrZTwGQUBM0w04Ncr_yXsrMTKxXM/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpHpAo3cYqoIv2nfKRFDqyEEuW0OhXO0wkv7cbr8FKXGl74iNaSySMx_iWwkIJrIugmBaXNNoeEpioerxGGAmZA9ECSUn-4zAe-wB-POoueoZiAK9zrZTwGQUBM0w04Ncr_yXsrMTKxXM/s640/Untitled.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
You can add other keys and values as you want as long as you don't change the original existing keys and values.&lt;br /&gt;
&lt;br /&gt;
Each World has a background image associated with it (you can also cut a big background into smaller pieces for each world and make a panorama landscape effect) - named World1.jpg, World2.jpg, etc.&lt;br /&gt;
&lt;br /&gt;
Credits to&amp;nbsp;&lt;a href="http://hawk9mm.deviantart.com/"&gt;http://hawk9mm.deviantart.com&lt;/a&gt; for the background images in this sample project.&lt;br /&gt;
&lt;br /&gt;
Customizable variable:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="CSharp" name="code"&gt;long levelsPerRow = 3; // CHANGE THIS TO WHAT YOU NEED (eg 5 levels per row etc)
&lt;/pre&gt;
&lt;br /&gt;
In GameScene.m, inside&amp;nbsp;&lt;span style="font-family: &amp;quot;menlo&amp;quot;; font-size: 11px;"&gt;didMoveToView&amp;nbsp;&lt;/span&gt;method, there is levelsPerRow variable that you can customize according to your liking. If you want to have 5 levels button per row, then change this to 5. Remember you need to make smaller level background images if you cramp more levels per row.&lt;br /&gt;
&lt;br /&gt;
To detect button taps, we set the name of playButton to the level number and detect it in touchesBegan.&lt;br /&gt;
&lt;br /&gt;
The rest is self explanatory I think. If you want to ask about anything, please comment. If you like this, share!
&lt;br /&gt;
&lt;a href="https://www.dropbox.com/s/gp6p8f6ekn7pjrn/SKScrollView.zip?dl=0"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwLxvdeV19GlIOwzASKbWSKhUwjBPNy2jxMLuw5rPaWHzsF1SOfJYjf_ENH8wqM3GOdC6-h8S_JLY2sPFMmZDH6-ITjy7jwshUUYhFuWCX9lIbvWoWh1J7s-ychzXOczOj_MzKWlH-hw/s320/download.png" /&gt;&lt;/a&gt;</description><link>http://xcodenoobies.blogspot.com/2015/09/skscrollview-skspritekit-scrollview-for.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwLxvdeV19GlIOwzASKbWSKhUwjBPNy2jxMLuw5rPaWHzsF1SOfJYjf_ENH8wqM3GOdC6-h8S_JLY2sPFMmZDH6-ITjy7jwshUUYhFuWCX9lIbvWoWh1J7s-ychzXOczOj_MzKWlH-hw/s72-c/download.png" width="72"/><thr:total>0</thr:total><enclosure length="-1" type="application/json" url="https://www.dropbox.com/s/gp6p8f6ekn7pjrn/SKScrollView.zip?dl=0"/><itunes:explicit/><itunes:subtitle>Hey guys how are you doing? Hope you are doing great. I have a sample project to share. Well, as usual, I wanted to do something and then search around and most of available solution is way too complicated or not to my liking. So I MAKE ONE MYSELF. YAYYYYYYY xD Great way to spend my Sunday evening with a cuppa coffee. So what I wanted to do is this: If you haven't already noticed, this is a screenshot from the famous game Cut The Rope. Aww come on you should know this everybody loves OM NOM! Look at him: XD Anyway, I wanted to have a scrollview of many worlds and each view has its own number of levels. Most solutions I found basically loads everything (all worlds all levels) into ONE SKScene. Wtf people. Good dev should avoid cramping everything and loading shitload of bytes into one scene.&amp;nbsp; So best way to do this is to make a General Scene and loads stuffs based on the world we're currently selecting. Check out the GIF below (this is what I created and sharing to you all for free :DDDDD) (Be patient the GIF is 1.1MB.) There is only one level selector scene file. And the scene calls itself based on which world currently is selected. Total Worlds is defined in the ViewController: // STARTING WORLD AND TOTAL WORLDS SET UP NSUserDefaults *def = [NSUserDefaults standardUserDefaults]; [def setInteger:1 forKey:@"World"]; [def setInteger:3 forKey:@"TotalWorld"]; [def synchronize]; If you want to have 5 Worlds to the project, please change the "3" to "5". You get the idea right. The "World" key is the "Current selected world" variable. Each world details are crafted inside PLISTs files inside the project - World1.plist for first world, World2.plist for second world, and so on. Each world plist has the following format: You can add other keys and values as you want as long as you don't change the original existing keys and values. Each World has a background image associated with it (you can also cut a big background into smaller pieces for each world and make a panorama landscape effect) - named World1.jpg, World2.jpg, etc. Credits to&amp;nbsp;http://hawk9mm.deviantart.com for the background images in this sample project. Customizable variable: long levelsPerRow = 3; // CHANGE THIS TO WHAT YOU NEED (eg 5 levels per row etc) In GameScene.m, inside&amp;nbsp;didMoveToView&amp;nbsp;method, there is levelsPerRow variable that you can customize according to your liking. If you want to have 5 levels button per row, then change this to 5. Remember you need to make smaller level background images if you cramp more levels per row. To detect button taps, we set the name of playButton to the level number and detect it in touchesBegan. The rest is self explanatory I think. If you want to ask about anything, please comment. If you like this, share!</itunes:subtitle><itunes:author>noreply@blogger.com (GeneCode)</itunes:author><itunes:summary>Hey guys how are you doing? Hope you are doing great. I have a sample project to share. Well, as usual, I wanted to do something and then search around and most of available solution is way too complicated or not to my liking. So I MAKE ONE MYSELF. YAYYYYYYY xD Great way to spend my Sunday evening with a cuppa coffee. So what I wanted to do is this: If you haven't already noticed, this is a screenshot from the famous game Cut The Rope. Aww come on you should know this everybody loves OM NOM! Look at him: XD Anyway, I wanted to have a scrollview of many worlds and each view has its own number of levels. Most solutions I found basically loads everything (all worlds all levels) into ONE SKScene. Wtf people. Good dev should avoid cramping everything and loading shitload of bytes into one scene.&amp;nbsp; So best way to do this is to make a General Scene and loads stuffs based on the world we're currently selecting. Check out the GIF below (this is what I created and sharing to you all for free :DDDDD) (Be patient the GIF is 1.1MB.) There is only one level selector scene file. And the scene calls itself based on which world currently is selected. Total Worlds is defined in the ViewController: // STARTING WORLD AND TOTAL WORLDS SET UP NSUserDefaults *def = [NSUserDefaults standardUserDefaults]; [def setInteger:1 forKey:@"World"]; [def setInteger:3 forKey:@"TotalWorld"]; [def synchronize]; If you want to have 5 Worlds to the project, please change the "3" to "5". You get the idea right. The "World" key is the "Current selected world" variable. Each world details are crafted inside PLISTs files inside the project - World1.plist for first world, World2.plist for second world, and so on. Each world plist has the following format: You can add other keys and values as you want as long as you don't change the original existing keys and values. Each World has a background image associated with it (you can also cut a big background into smaller pieces for each world and make a panorama landscape effect) - named World1.jpg, World2.jpg, etc. Credits to&amp;nbsp;http://hawk9mm.deviantart.com for the background images in this sample project. Customizable variable: long levelsPerRow = 3; // CHANGE THIS TO WHAT YOU NEED (eg 5 levels per row etc) In GameScene.m, inside&amp;nbsp;didMoveToView&amp;nbsp;method, there is levelsPerRow variable that you can customize according to your liking. If you want to have 5 levels button per row, then change this to 5. Remember you need to make smaller level background images if you cramp more levels per row. To detect button taps, we set the name of playButton to the level number and detect it in touchesBegan. The rest is self explanatory I think. If you want to ask about anything, please comment. If you like this, share!</itunes:summary><itunes:keywords>design, ios, levels, scroll, scrollview, selector, skspritekit, XCode</itunes:keywords></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-4755519886452740332</guid><pubDate>Wed, 12 Aug 2015 09:32:00 +0000</pubDate><atom:updated>2016-11-19T00:36:51.676-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">background</category><category domain="http://www.blogger.com/atom/ns#">fill</category><category domain="http://www.blogger.com/atom/ns#">seamless</category><category domain="http://www.blogger.com/atom/ns#">SKScene</category><category domain="http://www.blogger.com/atom/ns#">texture</category><title>SKSpriteKit: How to fill SKScene background with a Texture? (Code Snippet)</title><description>Yo guys.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Just submitted my latest iOS game. Check out the demo video here:&amp;nbsp;&lt;a href="https://www.youtube.com/watch?v=oOxtcHTD0c4"&gt;FreakOut - Tribute to Breakout (iOS Game)&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Anyways, I am updating one of my apps - Particle X to include the SpriteKit support. One thing that I need is to put a background texture to the SKScene background. In a normal UIView, we can simply specify self.view.backgroundColor = [UIColor colorWithPatternImage:yourUIImageHere]; and iOS will repeat that texture throughout the UIView. Which is cool.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
But unfortunately there is no such method in SKScene.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The simplest method, is to add a single big SKSpriteNode in the SKScene, behind everything else (you can do this by specifiying its .zPosition to something really negative like -1000). Big sprite, however eats memory.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
A better way (I think), is to auto repeat smaller sprites instead. This way you will not have any problem across different iOS screen sizes and the pattern appears similar without being stretched when screen sizes are different.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
BEHOLD!!!! CODESS!!!!!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;  
    float totW = 0;
    float totH = 0;
    int i = 0;
    int j = 0;
   SKTexture *tile = [SKTexture textureWithImage:img]

    while (totH&amp;lt;[[UIScreen mainScreen] bounds].size.height) {
        
        if (totW&amp;gt;=[[UIScreen mainScreen] bounds].size.width) { totW = 0; i =0; }
        
        while (totW&amp;lt;[[UIScreen mainScreen] bounds].size.width) {
            SKSpriteNode *bg = [SKSpriteNode spriteNodeWithTexture:tile];
            bg.zPosition = -100;
            bg.position = CGPointMake(i*tile.size.width, j*tile.size.height);
            
            [myScene addChild:bg];
            i ++;
            totW += tile.size.width;
        }
        
        
        j ++;
        totH += tile.size.height;
    }
&lt;/pre&gt;
&lt;br /&gt;
Note: img is your seamless texture image in UIImage format. You can load it by using UIImage *img = [UIImage imageNamed:@"tile.png"];. And myScene in the SKScene name.&lt;br /&gt;
&lt;br /&gt;
Check out the result:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkR-Zh5QANx-Poloc_W8IDcscFPCAsCHQbSsvZw5BsBjIOv6uUhIqlxXbhGvKKjrxtdmHoFMrMlnUDqnYPgNsXPO6PcrGS9QOLXzjw9Ct1L_AqYFQ_762aAtr5CU6b7d1TLNgZC3h3E48/s1600/iOS+Simulator+Screen+Shot+Aug+12%252C+2015%252C+5.24.38+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkR-Zh5QANx-Poloc_W8IDcscFPCAsCHQbSsvZw5BsBjIOv6uUhIqlxXbhGvKKjrxtdmHoFMrMlnUDqnYPgNsXPO6PcrGS9QOLXzjw9Ct1L_AqYFQ_762aAtr5CU6b7d1TLNgZC3h3E48/s320/iOS+Simulator+Screen+Shot+Aug+12%252C+2015%252C+5.24.38+PM.png" width="179" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
(iPhone 6 size)&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27EVEVqQ0cvPmIi_CDq_agZTiBJ-xKCabk9EBMtK5CCf961SvuT5PiWhCYh7YqlwSDSHT8DfeHlTqzpACcDvHkP2B2AT92JRiTyrIas-k3iFpXbTxM1aPOjvlWKSFiaPmLDvueTJwP-s/s1600/iOS+Simulator+Screen+Shot+Aug+12%252C+2015%252C+5.26.45+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27EVEVqQ0cvPmIi_CDq_agZTiBJ-xKCabk9EBMtK5CCf961SvuT5PiWhCYh7YqlwSDSHT8DfeHlTqzpACcDvHkP2B2AT92JRiTyrIas-k3iFpXbTxM1aPOjvlWKSFiaPmLDvueTJwP-s/s320/iOS+Simulator+Screen+Shot+Aug+12%252C+2015%252C+5.26.45+PM.png" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
(iPad 2 Size)&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
FYI: there is tile~ipad.png and there is tile@2x.png in the project - normal image assets arrangements.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
There is no downloadable sample project in this post since it is just a simple code snippet. Have fun and use as you like.&lt;/div&gt;
&lt;br /&gt;</description><link>http://xcodenoobies.blogspot.com/2015/08/skspritekit-how-to-fill-skscene.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkR-Zh5QANx-Poloc_W8IDcscFPCAsCHQbSsvZw5BsBjIOv6uUhIqlxXbhGvKKjrxtdmHoFMrMlnUDqnYPgNsXPO6PcrGS9QOLXzjw9Ct1L_AqYFQ_762aAtr5CU6b7d1TLNgZC3h3E48/s72-c/iOS+Simulator+Screen+Shot+Aug+12%252C+2015%252C+5.24.38+PM.png" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-7282746537168340657</guid><pubDate>Mon, 08 Jun 2015 06:36:00 +0000</pubDate><atom:updated>2016-11-19T00:37:24.306-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">border</category><category domain="http://www.blogger.com/atom/ns#">dev</category><category domain="http://www.blogger.com/atom/ns#">hack</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">outline</category><category domain="http://www.blogger.com/atom/ns#">SKLabelNode</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><title>How To: SKLabelNode Border Outline Quick Hack</title><description>Hey guys.&lt;br /&gt;
&lt;br /&gt;
Today I would like to share you a simple hack on SKLabelNode. Since it is a simple snippet, there will be no project to download.&lt;br /&gt;
&lt;br /&gt;
I am making my latest game (FreakOut) and was in need of SKLabelNode with outline. There are some 3rd party codes but I just want a simple and quick hack for it. So I made up this method:&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;  

-(void)popMessage:(NSString *)str {

    CGFloat fSize = 30*_xMult;
    SKLabelNode *msgLabel = [SKLabelNode labelNodeWithFontNamed:kFontName];
    msgLabel.text = str;
    msgLabel.zPosition = 100;
    msgLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
    msgLabel.fontSize = fSize;
    msgLabel.fontColor = [SKColor colorWithRed:1.0 green:0.3 blue:0.3 alpha:1.0];
    msgLabel.position = CGPointMake(_mySize.width/2.0, _mySize.height/2.0);
    [self addChild:msgLabel];
    
    SKAction *enlarge = [SKAction scaleTo:1.5 duration:0.8];
    SKAction *fadeOut = [SKAction fadeAlphaTo:0.5 duration:0.3];
    SKAction *remov = [SKAction removeFromParent];
    
    SKAction *doIt = [SKAction sequence:@[enlarge,fadeOut,remov]];
    
    [msgLabel runAction:doIt];

    // ourlines
    for (int i=1; i&amp;lt;=4; i++) {
        SKLabelNode *outline = [SKLabelNode labelNodeWithFontNamed:kFontName];
        outline.text = str;
        outline.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
        outline.fontSize = fSize;
        outline.fontColor = [SKColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
        if (i==1)  outline.position = CGPointMake(_mySize.width/2.0-2, _mySize.height/2.0+2);
        if (i==2)  outline.position = CGPointMake(_mySize.width/2.0+2, _mySize.height/2.0+2);
        if (i==3)  outline.position = CGPointMake(_mySize.width/2.0-2, _mySize.height/2.0-2);
        if (i==4)  outline.position = CGPointMake(_mySize.width/2.0+2, _mySize.height/2.0-2);
        [self addChild:outline];
        
        [outline runAction:doIt];
    }
 }

&lt;/pre&gt;
Ok. What I did was add another 4 SKLabelNode BEHIND the main label. Pretty crude but it works.&lt;br /&gt;
Positioning is important for each one.&lt;br /&gt;
&lt;br /&gt;
The result:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh26t_uuUuSOFl9p39sAKWohSElk4O7QD_HY63IGdSoQknBVWmBaHT66moyIwIL4-ilH_tOzAaNModIRdP3NWpG0DscXkxOlRmUyPa5aH4HZtLd0sVvkAxcXz8dDv34l00qo7SfT85L7UA/s1600/iOS+Simulator+Screen+Shot+Jun+8%252C+2015%252C+2.32.02+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh26t_uuUuSOFl9p39sAKWohSElk4O7QD_HY63IGdSoQknBVWmBaHT66moyIwIL4-ilH_tOzAaNModIRdP3NWpG0DscXkxOlRmUyPa5aH4HZtLd0sVvkAxcXz8dDv34l00qo7SfT85L7UA/s1600/iOS+Simulator+Screen+Shot+Jun+8%252C+2015%252C+2.32.02+PM.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Not bad eh? Feel free to use the code and improve upon it.</description><link>http://xcodenoobies.blogspot.com/2015/06/how-to-sklabelnode-border-outline-quick.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh26t_uuUuSOFl9p39sAKWohSElk4O7QD_HY63IGdSoQknBVWmBaHT66moyIwIL4-ilH_tOzAaNModIRdP3NWpG0DscXkxOlRmUyPa5aH4HZtLd0sVvkAxcXz8dDv34l00qo7SfT85L7UA/s72-c/iOS+Simulator+Screen+Shot+Jun+8%252C+2015%252C+2.32.02+PM.png" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-8765362080436023567</guid><pubDate>Thu, 29 Jan 2015 13:44:00 +0000</pubDate><atom:updated>2020-01-07T06:31:26.879-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">8</category><category domain="http://www.blogger.com/atom/ns#">8bit</category><category domain="http://www.blogger.com/atom/ns#">atari</category><category domain="http://www.blogger.com/atom/ns#">bit</category><category domain="http://www.blogger.com/atom/ns#">online</category><category domain="http://www.blogger.com/atom/ns#">retro</category><category domain="http://www.blogger.com/atom/ns#">speech</category><category domain="http://www.blogger.com/atom/ns#">synthesizer</category><category domain="http://www.blogger.com/atom/ns#">text</category><category domain="http://www.blogger.com/atom/ns#">to</category><category domain="http://www.blogger.com/atom/ns#">voice</category><title>Atari Online Voice Synthesizer</title><description>WAZZZUUPPPPP&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This is not a tutorial. But I have something cool for you. See I am in the making of my 5th iOS Game, then in need of some 8 bit voice. Freesound.org, gives me some. But I need to have it say a certain customized words. So I went on and search for the Atari Simulator for Mac. Found some, but I can't figure out how the heck do I install the speech simulator.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Upon searching further I encountered this cool online Voice Synthesizer that sounds exactly like the one I want - Atari version! So without further delay here is:&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHS8nJgFnrmmIRLkPNmj0xvBShCXMTQRX4xix_1cTivljq5BIOV6fvmO02C-CAHBjeAa-heG6ueQHZyqFrrZabKvsNNkCz2Ck_fcCwx03pd6FL_oOJ4SELcckh-KsG-OI8bY6TtO8eda0/s1600/atari_26001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHS8nJgFnrmmIRLkPNmj0xvBShCXMTQRX4xix_1cTivljq5BIOV6fvmO02C-CAHBjeAa-heG6ueQHZyqFrrZabKvsNNkCz2Ck_fcCwx03pd6FL_oOJ4SELcckh-KsG-OI8bY6TtO8eda0/s1600/atari_26001.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h2 style="text-align: center;"&gt;
&lt;span style="color: #b45f06;"&gt;ATARI ONLINE VOICE SYNTHESIZER&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;script src="https://www.dropbox.com/s/i5wjh7nbeiplrp0/sam.js?raw=1"&gt;&lt;/script&gt;


&lt;script&gt;

function PlayWebkit(context, audiobuffer)
{
 var source = context.createBufferSource();
 var soundBuffer = context.createBuffer(1, audiobuffer.length, 22050);
 var buffer = soundBuffer.getChannelData(0);
 for(var i=0; i&lt;audiobuffer.length; i++) buffer[i] = audiobuffer[i];
 source.buffer = soundBuffer;
 source.connect(context.destination);
 source.start(0); 
}

function PlayMozilla(context, audiobuffer)
{
 var written = context.mozWriteAudio(audiobuffer);
 var diff = audiobuffer.length - written;
 if (diff &lt;= 0) return;
 var buffer = new Float32Array(diff);
 for(var i = 0; i&lt;diff; i++) buffer[i] = audiobuffer[i+written];
 window.setTimeout(function(){PlayMozilla(context, buffer)}, 500);
}


function PlayBuffer(audiobuffer)
{
 if (typeof AudioContext !== "undefined") 
 {
        PlayWebkit(new AudioContext(), audiobuffer); 
 } else 
 if (typeof webkitAudioContext !== "undefined") 
 {
  PlayWebkit(new webkitAudioContext(), audiobuffer);
 } else if (typeof Audio !== "undefined")
 {
  var context = new Audio();
  context.mozSetup(1, 22050);
  PlayMozilla(context, audiobuffer);
 }
}

function Speak(text)
{
 //alert(text);

 var input = text;
 while (input.length &lt; 256) input += " ";
 var ptr = allocate(intArrayFromString(input), 'i8', ALLOC_STACK);
 _TextToPhonemes(ptr);
 //alert(Pointer_stringify(ptr));
 _SetInput(ptr);
 _Code39771();

 var bufferlength = Math.floor(_GetBufferLength()/50);
 var bufferptr = _GetBuffer();

 audiobuffer = new Float32Array(bufferlength);

 for(var i=0; i&lt;bufferlength; i++)
  audiobuffer[i] = ((getValue(bufferptr+i, 'i8')&amp;0xFF)-128)/256;
 PlayBuffer(audiobuffer);
}
&lt;/script&gt;

&lt;br /&gt;
&lt;h2&gt;
Well Poop.&lt;/h2&gt;
Blogger seems blocked my hosted js file.&lt;br /&gt;
But you can still get it to work on the original website:&lt;br /&gt;
&lt;a href="http://simulationcorner.net/index.php?page=sam"&gt;http://simulationcorner.net/index.php?page=sam.&amp;nbsp;&lt;/a&gt;</description><link>http://xcodenoobies.blogspot.com/2015/01/atari-online-voice-synthesizer.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHS8nJgFnrmmIRLkPNmj0xvBShCXMTQRX4xix_1cTivljq5BIOV6fvmO02C-CAHBjeAa-heG6ueQHZyqFrrZabKvsNNkCz2Ck_fcCwx03pd6FL_oOJ4SELcckh-KsG-OI8bY6TtO8eda0/s72-c/atari_26001.png" width="72"/><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4212984476274343535.post-4843318980882249024</guid><pubDate>Sat, 06 Dec 2014 01:22:00 +0000</pubDate><atom:updated>2016-11-19T00:43:38.635-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">multiline</category><category domain="http://www.blogger.com/atom/ns#">SKLabelNode</category><category domain="http://www.blogger.com/atom/ns#">Spritekit</category><category domain="http://www.blogger.com/atom/ns#">stackoverflow</category><category domain="http://www.blogger.com/atom/ns#">tutorial</category><category domain="http://www.blogger.com/atom/ns#">XCode</category><title>Multiline SKLabelNode? Hell Yes Please XD</title><description>Woah. Another Noobies Tutorial yayyyyyy....&lt;br /&gt;
&lt;br /&gt;
Apple, naughty Apple. You made SpriteKit and SKLabelNode, but not make multiline labelnode. This is supposed to be expected!! OMG!! UILabel has multiline function, why not SKLabelNode?&lt;br /&gt;
&lt;br /&gt;
Ok, lets not get crazy. Relax I am here to solve your woes.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://www.dropbox.com/s/e6ex3419vcj05hx/MultiLine.zip?dl=0" style="clear: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwLxvdeV19GlIOwzASKbWSKhUwjBPNy2jxMLuw5rPaWHzsF1SOfJYjf_ENH8wqM3GOdC6-h8S_JLY2sPFMmZDH6-ITjy7jwshUUYhFuWCX9lIbvWoWh1J7s-ychzXOczOj_MzKWlH-hw/s320/download.png" /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
As normal, I make this simple method to handle multiline SKLabelNode. Before we go on,&lt;br /&gt;
I'd like to give you alternatives (because some people already make some solution).&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://github.com/downrightsimple/DSMultilineLabelNode" style="background: rgb(255, 255, 255); border: 0px; color: #4a6b82; cursor: pointer; font-family: Arial, 'Liberation Sans', 'DejaVu Sans', sans-serif; font-size: 14px; line-height: 17.8048000335693px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;https://github.com/downrightsimple/DSMultilineLabelNode&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The above isn't really a labelnode object. What it does is write down all the text with labelnode on a dummy space and capture it as image, and use that image as labels. Basically in your app it becomes SKSpritenode. This maybe is ok if you want a quick implementation. But capturing things into an image has lots of problems - namely memory usage, sizes (for example you need to cater for bigger screens making sure the image is not pixelated at high res, etc, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://github.com/nickfalk/NORLabelNode"&gt;https://github.com/nickfalk/NORLabelNode&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The second method above is probably what you want if you prefer to have SKLabelNode that can use the "\n" (linebreaks). This is OK-ish. But I really don't like manually putting the line breaks. Especially if I change the wording then the line breaks need to be redone again, which SUCKSKKKKSK... but this solution is actually not bad.&lt;br /&gt;
&lt;br /&gt;
OKAY! My method (which is obviously the best and smartest method XD) is to use SKLabelNodes, auto creating them through for loops depending on the length of string you have. You specify the rough character width per line, and this method autowraps it. It's like MAGIC. I know you will like this 10million times. XD&lt;br /&gt;
&lt;br /&gt;
This is how the app will look like when you run it. Those are SKLabelNodes!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF6973rANhZuBQj-dPV6Qh0Ndk61TC65i9-6-iUCpQM9no6r5jQwzFXKaH6TzPhUgg_XqqbsgiGVTzAkNwsTm5Hz0voJjdhIo81wHJRy9R7TPI_02pV1k0rcTcZEi7juNNNVx4xivO4kY/s1600/iOS+Simulator+Screen+Shot+Dec+5,+2014,+11.43.19+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF6973rANhZuBQj-dPV6Qh0Ndk61TC65i9-6-iUCpQM9no6r5jQwzFXKaH6TzPhUgg_XqqbsgiGVTzAkNwsTm5Hz0voJjdhIo81wHJRy9R7TPI_02pV1k0rcTcZEi7juNNNVx4xivO4kY/s1600/iOS+Simulator+Screen+Shot+Dec+5,+2014,+11.43.19+PM.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Ok now for the code. Read the comments to understand what each line does.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;// For the sake of testing, I just use a dummy NSString and hardcode the string I want to display. 
// This string can be anything - even a string of paragraph that you retrieve from the web or pdf or whatever.
NSString *tmp = @"This is a long string where you do not need to bother about linebreaks and my method breaks it up into multiple SKLabelNode to roughly fit a customized width. Yep it works."; // long string - just type whatever in here
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
// parse through the string and put each words into an array.
NSCharacterSet *separators = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSArray *words = [tmp componentsSeparatedByCharactersInSet:separators];
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
int len = [tmp length];
int width = 20; // specify your own width to fit the device screen
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
// get the number of labelnode we need.
int totLines = len/width + 1;
int cnt = 0; // used to parse through the words array
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
// here is the for loop that create all the SKLabelNode that we need to&amp;nbsp;
// display the string.

for (int i=0; i&amp;lt;totlines; i++) {
 int lenPerLine = 0;
            NSString *lineStr = @"";
            
            while (lenPerLine&amp;lt;width) {
                if (cnt&amp;gt;[words count]-1) break; // failsafe - avoid overflow error 
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lineStr = [NSString stringWithFormat:@"%@ %@", lineStr, words[cnt]];
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lenPerLine = [lineStr length];
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cnt ++;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // NSLog(@"%@", lineStr);
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
 // creation of the SKLabelNode itself
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SKLabelNode *_multiLineLabel = [SKLabelNode labelNodeWithFontNamed:@"Oxygen Light"];
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.text = lineStr;
 // name each label node so you can animate it if u wish
 // the rest of the code should be self-explanatory
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.name = [NSString stringWithFormat:@"line%d",i];
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.fontSize = 20;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.fontColor = [SKColor colorWithRed:1 green:1 blue:1.0 alpha:1.0];
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.position = CGPointMake(size.width/2, size.height/2+100-20*i);
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [self addChild:_multiLineLabel];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
So that's all. Easy right? Feel free to improve it more. This method is ideal for games in SpriteKits.&lt;br /&gt;
For example when you want to make credits info, or a short storyline, or some instructions. It makes&lt;br /&gt;
creating and positioning the multiline text easy.&lt;br /&gt;
&lt;br /&gt;
Have fun!&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://www.dropbox.com/s/e6ex3419vcj05hx/MultiLine.zip?dl=0" style="clear: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwLxvdeV19GlIOwzASKbWSKhUwjBPNy2jxMLuw5rPaWHzsF1SOfJYjf_ENH8wqM3GOdC6-h8S_JLY2sPFMmZDH6-ITjy7jwshUUYhFuWCX9lIbvWoWh1J7s-ychzXOczOj_MzKWlH-hw/s320/download.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Edit: Shaun Hirst made a Swift Version (thanks mate)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="obj-c"&gt;

func addMultilineText(Val: CGFloat )-&amp;gt; CGFloat  
 {  
   var Returnval = Val  
   let tmp = "This is a long string where you do not need to bother about linebreaks and my method breaks it up into multiple SKLabelNode to roughly fit a customized width. Yep it works."; // long string - just type whatever in here  
   // parse through the string and put each words into an array.  
   let separators = NSCharacterSet.whitespaceAndNewlineCharacterSet()  
   let words = tmp.componentsSeparatedByCharactersInSet(separators)  
   let len = countElements(tmp)  
   let width = 40; // specify your own width to fit the device screen  
   // get the number of labelnode we need.  
   let totLines = len/width+1  
   var cnt = 0; // used to parse through the words array  
   // here is the for loop that create all the SKLabelNode that we need to  
   // display the string.  
   for ( var i = 0; i &amp;lt; totLines; ++i )  
   {  
     var lenPerLine = 0  
     var lineStr = ""  
     while lenPerLine &amp;lt; width  
     {  
       if cnt &amp;gt; words.count-1  
       {  
         break  
       }  
       else  
       {  
         lineStr = NSString(format: "%@ %@", lineStr, words[cnt])  
         lenPerLine = countElements(lineStr)  
         cnt++  
       }  
     }  
     // creation of the SKLabelNode itself  
     var _multiLineLabel = SKLabelNode(fontNamed: "Oxygen Light")  
     _multiLineLabel.text = lineStr;  
     // name each label node so you can animate it if u wish  
     // the rest of the code should be self-explanatory  
     _multiLineLabel.name = NSString(format: "line%d", i)  
     _multiLineLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Center  
     _multiLineLabel.fontSize = 16;  
     _multiLineLabel.fontColor = UIColor.whiteColor()  
     let Top = Val-20*CGFloat(i)  
     _multiLineLabel.position = CGPointMake( self.size.width/2 , Top )  
     self.sharedInstance.addChildFadeIn(_multiLineLabel, target: self)  
     Returnval = Top;  
   }  
   // return last y pos sp we can add stuff under it  
   return Returnval  
 }  

&lt;/code&gt;&lt;/pre&gt;</description><link>http://xcodenoobies.blogspot.com/2014/12/multiline-sklabelnode-hell-yes-please-xd.html</link><author>noreply@blogger.com (GeneCode)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwLxvdeV19GlIOwzASKbWSKhUwjBPNy2jxMLuw5rPaWHzsF1SOfJYjf_ENH8wqM3GOdC6-h8S_JLY2sPFMmZDH6-ITjy7jwshUUYhFuWCX9lIbvWoWh1J7s-ychzXOczOj_MzKWlH-hw/s72-c/download.png" width="72"/><thr:total>7</thr:total><enclosure length="-1" type="application/json" url="https://www.dropbox.com/s/e6ex3419vcj05hx/MultiLine.zip?dl=0"/><itunes:explicit/><itunes:subtitle>Woah. Another Noobies Tutorial yayyyyyy.... Apple, naughty Apple. You made SpriteKit and SKLabelNode, but not make multiline labelnode. This is supposed to be expected!! OMG!! UILabel has multiline function, why not SKLabelNode? Ok, lets not get crazy. Relax I am here to solve your woes. As normal, I make this simple method to handle multiline SKLabelNode. Before we go on, I'd like to give you alternatives (because some people already make some solution). https://github.com/downrightsimple/DSMultilineLabelNode The above isn't really a labelnode object. What it does is write down all the text with labelnode on a dummy space and capture it as image, and use that image as labels. Basically in your app it becomes SKSpritenode. This maybe is ok if you want a quick implementation. But capturing things into an image has lots of problems - namely memory usage, sizes (for example you need to cater for bigger screens making sure the image is not pixelated at high res, etc, etc). https://github.com/nickfalk/NORLabelNode The second method above is probably what you want if you prefer to have SKLabelNode that can use the "\n" (linebreaks). This is OK-ish. But I really don't like manually putting the line breaks. Especially if I change the wording then the line breaks need to be redone again, which SUCKSKKKKSK... but this solution is actually not bad. OKAY! My method (which is obviously the best and smartest method XD) is to use SKLabelNodes, auto creating them through for loops depending on the length of string you have. You specify the rough character width per line, and this method autowraps it. It's like MAGIC. I know you will like this 10million times. XD This is how the app will look like when you run it. Those are SKLabelNodes! Ok now for the code. Read the comments to understand what each line does. // For the sake of testing, I just use a dummy NSString and hardcode the string I want to display. // This string can be anything - even a string of paragraph that you retrieve from the web or pdf or whatever. NSString *tmp = @"This is a long string where you do not need to bother about linebreaks and my method breaks it up into multiple SKLabelNode to roughly fit a customized width. Yep it works."; // long string - just type whatever in here &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // parse through the string and put each words into an array. NSCharacterSet *separators = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSArray *words = [tmp componentsSeparatedByCharactersInSet:separators]; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int len = [tmp length]; int width = 20; // specify your own width to fit the device screen &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // get the number of labelnode we need. int totLines = len/width + 1; int cnt = 0; // used to parse through the words array &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // here is the for loop that create all the SKLabelNode that we need to&amp;nbsp; // display the string. for (int i=0; i&amp;lt;totlines; i++) { int lenPerLine = 0; NSString *lineStr = @""; while (lenPerLine&amp;lt;width) { if (cnt&amp;gt;[words count]-1) break; // failsafe - avoid overflow error &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lineStr = [NSString stringWithFormat:@"%@ %@", lineStr, words[cnt]]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lenPerLine = [lineStr length]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cnt ++; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // NSLog(@"%@", lineStr); &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } // creation of the SKLabelNode itself &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SKLabelNode *_multiLineLabel = [SKLabelNode labelNodeWithFontNamed:@"Oxygen Light"]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.text = lineStr; // name each label node so you can animate it if u wish // the rest of the code should be self-explanatory &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.name = [NSString stringWithFormat:@"line%d",i]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.fontSize = 20; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.fontColor = [SKColor colorWithRed:1 green:1 blue:1.0 alpha:1.0]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.position = CGPointMake(size.width/2, size.height/2+100-20*i); &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [self addChild:_multiLineLabel]; } So that's all. Easy right? Feel free to improve it more. This method is ideal for games in SpriteKits. For example when you want to make credits info, or a short storyline, or some instructions. It makes creating and positioning the multiline text easy. Have fun! Edit: Shaun Hirst made a Swift Version (thanks mate) func addMultilineText(Val: CGFloat )-&amp;gt; CGFloat { var Returnval = Val let tmp = "This is a long string where you do not need to bother about linebreaks and my method breaks it up into multiple SKLabelNode to roughly fit a customized width. Yep it works."; // long string - just type whatever in here // parse through the string and put each words into an array. let separators = NSCharacterSet.whitespaceAndNewlineCharacterSet() let words = tmp.componentsSeparatedByCharactersInSet(separators) let len = countElements(tmp) let width = 40; // specify your own width to fit the device screen // get the number of labelnode we need. let totLines = len/width+1 var cnt = 0; // used to parse through the words array // here is the for loop that create all the SKLabelNode that we need to // display the string. for ( var i = 0; i &amp;lt; totLines; ++i ) { var lenPerLine = 0 var lineStr = "" while lenPerLine &amp;lt; width { if cnt &amp;gt; words.count-1 { break } else { lineStr = NSString(format: "%@ %@", lineStr, words[cnt]) lenPerLine = countElements(lineStr) cnt++ } } // creation of the SKLabelNode itself var _multiLineLabel = SKLabelNode(fontNamed: "Oxygen Light") _multiLineLabel.text = lineStr; // name each label node so you can animate it if u wish // the rest of the code should be self-explanatory _multiLineLabel.name = NSString(format: "line%d", i) _multiLineLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Center _multiLineLabel.fontSize = 16; _multiLineLabel.fontColor = UIColor.whiteColor() let Top = Val-20*CGFloat(i) _multiLineLabel.position = CGPointMake( self.size.width/2 , Top ) self.sharedInstance.addChildFadeIn(_multiLineLabel, target: self) Returnval = Top; } // return last y pos sp we can add stuff under it return Returnval }</itunes:subtitle><itunes:author>noreply@blogger.com (GeneCode)</itunes:author><itunes:summary>Woah. Another Noobies Tutorial yayyyyyy.... Apple, naughty Apple. You made SpriteKit and SKLabelNode, but not make multiline labelnode. This is supposed to be expected!! OMG!! UILabel has multiline function, why not SKLabelNode? Ok, lets not get crazy. Relax I am here to solve your woes. As normal, I make this simple method to handle multiline SKLabelNode. Before we go on, I'd like to give you alternatives (because some people already make some solution). https://github.com/downrightsimple/DSMultilineLabelNode The above isn't really a labelnode object. What it does is write down all the text with labelnode on a dummy space and capture it as image, and use that image as labels. Basically in your app it becomes SKSpritenode. This maybe is ok if you want a quick implementation. But capturing things into an image has lots of problems - namely memory usage, sizes (for example you need to cater for bigger screens making sure the image is not pixelated at high res, etc, etc). https://github.com/nickfalk/NORLabelNode The second method above is probably what you want if you prefer to have SKLabelNode that can use the "\n" (linebreaks). This is OK-ish. But I really don't like manually putting the line breaks. Especially if I change the wording then the line breaks need to be redone again, which SUCKSKKKKSK... but this solution is actually not bad. OKAY! My method (which is obviously the best and smartest method XD) is to use SKLabelNodes, auto creating them through for loops depending on the length of string you have. You specify the rough character width per line, and this method autowraps it. It's like MAGIC. I know you will like this 10million times. XD This is how the app will look like when you run it. Those are SKLabelNodes! Ok now for the code. Read the comments to understand what each line does. // For the sake of testing, I just use a dummy NSString and hardcode the string I want to display. // This string can be anything - even a string of paragraph that you retrieve from the web or pdf or whatever. NSString *tmp = @"This is a long string where you do not need to bother about linebreaks and my method breaks it up into multiple SKLabelNode to roughly fit a customized width. Yep it works."; // long string - just type whatever in here &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // parse through the string and put each words into an array. NSCharacterSet *separators = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSArray *words = [tmp componentsSeparatedByCharactersInSet:separators]; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int len = [tmp length]; int width = 20; // specify your own width to fit the device screen &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // get the number of labelnode we need. int totLines = len/width + 1; int cnt = 0; // used to parse through the words array &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // here is the for loop that create all the SKLabelNode that we need to&amp;nbsp; // display the string. for (int i=0; i&amp;lt;totlines; i++) { int lenPerLine = 0; NSString *lineStr = @""; while (lenPerLine&amp;lt;width) { if (cnt&amp;gt;[words count]-1) break; // failsafe - avoid overflow error &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lineStr = [NSString stringWithFormat:@"%@ %@", lineStr, words[cnt]]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lenPerLine = [lineStr length]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cnt ++; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // NSLog(@"%@", lineStr); &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } // creation of the SKLabelNode itself &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SKLabelNode *_multiLineLabel = [SKLabelNode labelNodeWithFontNamed:@"Oxygen Light"]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.text = lineStr; // name each label node so you can animate it if u wish // the rest of the code should be self-explanatory &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.name = [NSString stringWithFormat:@"line%d",i]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.fontSize = 20; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.fontColor = [SKColor colorWithRed:1 green:1 blue:1.0 alpha:1.0]; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _multiLineLabel.position = CGPointMake(size.width/2, size.height/2+100-20*i); &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [self addChild:_multiLineLabel]; } So that's all. Easy right? Feel free to improve it more. This method is ideal for games in SpriteKits. For example when you want to make credits info, or a short storyline, or some instructions. It makes creating and positioning the multiline text easy. Have fun! Edit: Shaun Hirst made a Swift Version (thanks mate) func addMultilineText(Val: CGFloat )-&amp;gt; CGFloat { var Returnval = Val let tmp = "This is a long string where you do not need to bother about linebreaks and my method breaks it up into multiple SKLabelNode to roughly fit a customized width. Yep it works."; // long string - just type whatever in here // parse through the string and put each words into an array. let separators = NSCharacterSet.whitespaceAndNewlineCharacterSet() let words = tmp.componentsSeparatedByCharactersInSet(separators) let len = countElements(tmp) let width = 40; // specify your own width to fit the device screen // get the number of labelnode we need. let totLines = len/width+1 var cnt = 0; // used to parse through the words array // here is the for loop that create all the SKLabelNode that we need to // display the string. for ( var i = 0; i &amp;lt; totLines; ++i ) { var lenPerLine = 0 var lineStr = "" while lenPerLine &amp;lt; width { if cnt &amp;gt; words.count-1 { break } else { lineStr = NSString(format: "%@ %@", lineStr, words[cnt]) lenPerLine = countElements(lineStr) cnt++ } } // creation of the SKLabelNode itself var _multiLineLabel = SKLabelNode(fontNamed: "Oxygen Light") _multiLineLabel.text = lineStr; // name each label node so you can animate it if u wish // the rest of the code should be self-explanatory _multiLineLabel.name = NSString(format: "line%d", i) _multiLineLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Center _multiLineLabel.fontSize = 16; _multiLineLabel.fontColor = UIColor.whiteColor() let Top = Val-20*CGFloat(i) _multiLineLabel.position = CGPointMake( self.size.width/2 , Top ) self.sharedInstance.addChildFadeIn(_multiLineLabel, target: self) Returnval = Top; } // return last y pos sp we can add stuff under it return Returnval }</itunes:summary><itunes:keywords>ios, multiline, SKLabelNode, Spritekit, stackoverflow, tutorial, XCode</itunes:keywords></item></channel></rss>