<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>James Van Dyne &#187; iPhone</title>
	<atom:link href="http://www.james-vandyne.com/category/iphone/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.james-vandyne.com</link>
	<description>The Life and Times</description>
	<lastBuildDate>Sat, 08 Oct 2011 16:11:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Creating Universal Overlays Using UIViews on iOS</title>
		<link>http://www.james-vandyne.com/creating-universal-overlays-using-uiviews-on-ios/</link>
		<comments>http://www.james-vandyne.com/creating-universal-overlays-using-uiviews-on-ios/#comments</comments>
		<pubDate>Sun, 31 Oct 2010 11:23:44 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=132</guid>
		<description><![CDATA[What happens when you are developing a UIViewController based application and you want to have an simple transparent overlay for displaying things, say a custom achievements UI in a game, or anything really. In my case, I had a singleton &#8230; <a href="http://www.james-vandyne.com/creating-universal-overlays-using-uiviews-on-ios/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>What happens when you are developing a UIViewController based application and you want to have an simple transparent overlay for displaying things, say a custom achievements UI in a game, or anything really.</p>

<p>In my case, I had a singleton that handles all interactions with GameCenter, called DAGameCenter. With this, anywhere in my application I could simply report an achievement with a single call:</p>

<pre class="code">
[[DAGameCenter sharedGameCenter] reportAchievement:@"com.mygame.achievement" 
                                 percent:100.0f];
</pre>

<p>DAGameCenter then tries to report the achievement to GameCenter and if it fails, archives it in a list of achievements to try reporting at another time. The proble comes in, as you probably guessed it, having a uniform method of displaying achievements to the user across all screens.</p>

<p>My first idea was to simply use a new UIWindow. UIWindow has properties for order the level of each window. I could simply create a new UIWindow, set the level to be above my keyWindow, and simply forward all events to my keyWindow so the user can still interact with the window below.</p>

<h3>Problem</h3>

<p>Apple advises against creating more than one UIWindow object. Your UIWindow is also already created for you by UIApplication when your app launches. So, things aren&#8217;t as simple as we would hope.</p>

<p>We can move up the object hierarchy a little bit to UIView, UIWindow&#8217;s parent class. We can simply put this view on top of our main view and all is peachy, right? Something like</p>

<pre class="code">
OverlayView *myOverlay = [[OverlayView alloc] initWithFrame:frame];
[[[UIApplication sharedApplication] keyWindow] addSubView:myOverlay];
</pre>

<p>Not quite&#8230;simply adding a UIView to our existing UIWindow causes our interface to become unresponsive. This is because our newly added view is capturing all events. As our view doesn&#8217;t handle any events, it simply forwards the event up the responder chain, to our UIWindow, which then forwards it to our UIApplication, and then the event is ignored.</p>

<p>Our mainView and  our overlayViews are not parent-child but they are both siblings of our UIWindow. This, in effect, creates our overlayView creates a second hierarchy of views in our application.</p>

<p>A quick and dirty solution would be to simply add a delegate to our overlayView and when creating our ourlayView set our mainView as the delegate. What happens when we push a second view above our mainView, say a settings screen. Our settings will become unresponsive unless we also remember to update our delegate.</p>

<p>So, this solution effectively loses maintainability after expanding beyond a single view and requires us to actively remember to set our delegates with navigation. It&#8217;s just asking for problems.</p>

<p>Our problems are two-fold: locating the view that is currently being displayed and then forwarding events to said view.</p>

<h3>Solution</h3>

<p>Forwarding events is quite simple. We simply need to overwrite the hitTest:withEvent method in our view.</p>

<p>It turns out that you can access a given view&#8217;s subviews with a simple call to&#8230;subviews. This returns an array, that&#8217;s helpfully ordered from back to front. UIView has a method that allows us to insert views above other views. UIWindow is a subclass of UIView, so all of this applies to it as well. We can gain access to an ordered array our subviews of our window anywhere in our application by simply calling subviews on our keyWindow.</p>

<p>As I&#8217;m sure you can probably guess by now, the solution. We simply need to insert our overlayView above our UIWindow. Then, we can forward events to the back-most subview that our window has.</p>

<p>When we push a modal view on to our UI to change screens from mainView to settings, it actually removes our mainView from our view hierarchy and replaces it with our settings view. This means that the &#8220;active&#8221; view will always be at 0.</p>

<p>All together, our code looks something like as follows:</p>

<pre class="code">

// Somewhere in our Singleton. Add our view so it is always above all views in our window
// In my case, I have it in the block that runs when a player is authenticated with GameCenter
-(void)insertAchievementView {
    UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
    if(!_achievementView)
        _achievementView = [[DAAchievementView alloc] initWithFrame:[mainWindow frame]];
    [mainWindow insertSubview:_achievementView aboveSubview:mainWindow];
}

// Then, in our actual achievementView, forward our hitTests
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    return [[[[[UIApplication sharedApplication] keyWindow] subviews] objectAtIndex:0] hitTest:point withEvent:event];
}
</pre>

<h3>Conclusion</h3>

<p>We can mimic the usage of a second UIWindow for displaying achievements of our application with a simple overlay view. Integrating the appropriate display methods of our overlay view in our singleton allows decoupling of the overlay and the view behind it, greatly reducing complexity. Furthermore, this decoupling allows all views in our application to utilize the overlay &#8220;for free&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/creating-universal-overlays-using-uiviews-on-ios/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>60 songs, 60 minutes&#8230; can you guess them all?</title>
		<link>http://www.james-vandyne.com/60-songs-60-minutes-can-you-guess-them-all/</link>
		<comments>http://www.james-vandyne.com/60-songs-60-minutes-can-you-guess-them-all/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 13:57:14 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[DisposableApps]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=50</guid>
		<description><![CDATA[In August I began work on Disposable Apps. A new company focusing on iPhone software with my friend Jacob Wyke. Our first application was to be called Powerhour, after a popular musical drinking game. We built the application and submitted &#8230; <a href="http://www.james-vandyne.com/60-songs-60-minutes-can-you-guess-them-all/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In August I began work on Disposable Apps. A new company focusing on iPhone software with my friend Jacob Wyke. Our first application was to be called Powerhour, after a popular musical drinking game.</p>

<p>We built the application and submitted it near the beginning of September. 3 weeks later I got an email from Apple telling me that they had been trying to contact me and asked me for my phone number. After finishing the application and submitting the application I got a phone call from apple telling me that they didn&#8217;t accept Powerhour applications because it encourages consumption of something.</p>

<p>That single phone call singly handily killed a lot of excitement about the application for us, so we shelved it for a few months while I worked on Jisho.</p>

<p>Last week we picked it back up and reworked the idea a little bit and resubmitted. It only took 2 days for approval and I&#8217;m proud to announce that DisposableApps&#8217; first application, <a href="http://www.disposableapps.com/pubtunes/?utm_source=jvd&#038;utm_medium=blog" title="Check out Pubtunes">Pubtunes</a> is on the app store.</p>

<p><a href="http://www.disposableapps.com/pubtunes/?utm_source=sugoisoft&#038;utm_medium=blog"><img src="http://www.james-vandyne.com/wp-content/images/2010/pubtunes.png" alt="Pubtunes - 60 songs, 60 sminutes... can you guess them all?"/></a></p>

<p>So please check it out. Let me know what you think.</p>

<p>As always, there is more to come from us.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/60-songs-60-minutes-can-you-guess-them-all/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improve Performance and Draw Your Own Strings on iPhone</title>
		<link>http://www.james-vandyne.com/improve-performance-and-draw-your-own-strings-on-iphone/</link>
		<comments>http://www.james-vandyne.com/improve-performance-and-draw-your-own-strings-on-iphone/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 11:16:34 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=20</guid>
		<description><![CDATA[Introduction Programmers are lazy. If you are going to have some no-frills text on the screen that does not change too often an UILabel is the way to go. Changing the is very simple. It&#8217;s just a matter of: myLabel.text &#8230; <a href="http://www.james-vandyne.com/improve-performance-and-draw-your-own-strings-on-iphone/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>

<p>Programmers are lazy. If you are going to have some no-frills text on the screen that does not change too often an UILabel is the way to go. Changing the is very simple. It&#8217;s just a matter of:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">myLabel.text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Change that text!&quot;</span>;</pre></div></div>


<p>What happens when you do this, every second for 45+ minutes (that&#8217;s 2700+ updates)?</p>

<h3>Problem</h3>

<p>I noticed that with every update of that label in the manner above my consumed ram was growing. Not a lot, but a few bytes. Enough though that after 2700+ times, it was causing some problems. I must be leaking I thought. Pop up Instruments with Leaks and test. No leakage apparent. Perhaps it was getting cached somewhere in UIKit?</p>

<p>As my application was going to be getting the proof-of-concept UI completely rewritten, UILabel was going to be a placeholder unless I could be a good lazy programmer and continue to use them.</p>

<p>However with UILabel seemingly cacheing the old labels or something, using them is out of the question.</p>

<h3>Solution</h3>

<p>Most programmers aren&#8217;t going to be updating their labels very often. Let alone 2700+ times every second.</p>

<p>My solution was a combination of Quartz2D (to change the color of the string) and NSString&#8217;s drawing categories.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>drawRect<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGRect<span style="color: #002200;">&#41;</span>rect <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Get the current context so we can draw.</span>
	CGContextRef context <span style="color: #002200;">=</span> UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Set the fill color to white. </span>
	CGContextSetFillColorWithColor<span style="color: #002200;">&#40;</span>context, <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIColor whiteColor<span style="color: #002200;">&#93;</span> CGColor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>; 
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Draw in the specified rect</span>
	<span style="color: #002200;">&#91;</span>myString drawInRect<span style="color: #002200;">:</span>rect withFont<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIFont fontWithName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Helvetica&quot;</span> size<span style="color: #002200;">:</span><span style="color: #2400d9;">16.0</span><span style="color: #002200;">&#93;</span>  lineBreakMode<span style="color: #002200;">:</span>UILineBreakModeTailTruncation alignment<span style="color: #002200;">:</span>UITextAlignmentCenter<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Notes:</p>

<ul>
<li>This assumes that you have a property myString declared somewhere. </li>
<li>You could probably improve performance a bit by cacheing the UIFont. </li>
<li>By drawing our own strings we lose the convenience of having a CALayer ready to use.</li>
</ul>

<h3>Conclusion</h3>

<p>I used the above code (of course modified for posting)  in my application and poof my application was no longer growing. Moreover, it actually feels a bit snappier.</p>

<p>UILabel is great for displaying static or mostly static text on the screen. However if you are going to be updating it with any frequency, it is advantageous to draw text manually. UILabel uses the drawInRect: or drawAtPoint: methods to draw anyways, calling them directly saves your phone from a lot of unneeded calls. This equates to less execution faster which in turn means more battery life for your users. A win for everybody.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/improve-performance-and-draw-your-own-strings-on-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

