<?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>Stringbean&#039;s Blog</title>
	<atom:link href="http://purpledragonsoftware.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://purpledragonsoftware.com/blog</link>
	<description>Where technology, photography and canoeing collide</description>
	<lastBuildDate>Mon, 23 Jan 2012 22:40:34 +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>Custom gradient controls for iOS</title>
		<link>http://purpledragonsoftware.com/blog/2012/01/custom-gradient-controls-for-ios/</link>
		<comments>http://purpledragonsoftware.com/blog/2012/01/custom-gradient-controls-for-ios/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 21:51:39 +0000</pubDate>
		<dc:creator>stringbean</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[custom control]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[uicontrol]]></category>

		<guid isPermaLink="false">http://purpledragonsoftware.com/blog/?p=141</guid>
		<description><![CDATA[Recently I needed custom UI control for iOS that had rounded corners and a gradient background. To make the user<a href="http://purpledragonsoftware.com/blog/2012/01/custom-gradient-controls-for-ios/" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Recently I needed custom UI control for iOS that had rounded corners and a gradient background. To make the user experience as rich as possible I wanted the background of the control to flatten when the user tapped it. There were plenty of examples of gradient buttons and rounded corner views but nothing did exactly what I needed.</p>

<p>After a bit of experimentation I found the easiest solution was to add a gradient layer to a custom UIControl and swap it with a different layer when the control became highlighted.<span id="more-141"></span></p>

<p>The first step was to was to create a custom UIControl class and add a gradient background layer:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;QuartzCore/QuartzCore.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> GradientControl <span style="color: #002200;">:</span> UIControl
<span style="color: #002200;">&#123;</span>
    CAGradientLayer <span style="color: #002200;">*</span>normalBackground;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> GradientControl
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span> initWithCoder<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSCoder</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>aDecoder
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super initWithCoder<span style="color: #002200;">:</span>aDecoder<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        self.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor clearColor<span style="color: #002200;">&#93;</span>;
&nbsp;
        normalBackground <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CAGradientLayer layer<span style="color: #002200;">&#93;</span>;
        normalBackground.frame <span style="color: #002200;">=</span> self.bounds;
        normalBackground.cornerRadius <span style="color: #002200;">=</span> <span style="color: #2400d9;">10</span>;
        normalBackground.borderWidth <span style="color: #002200;">=</span> <span style="color: #2400d9;">1</span>;
        normalBackground.borderColor <span style="color: #002200;">=</span> <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>;
&nbsp;
        normalBackground.colors <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSArray</span> arrayWithObjects<span style="color: #002200;">:</span>
                                   <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIColor colorWithHexString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;a9aeba&quot;</span><span style="color: #002200;">&#93;</span> CGColor<span style="color: #002200;">&#93;</span>,
                                   <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIColor colorWithHexString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;7e8790&quot;</span><span style="color: #002200;">&#93;</span> CGColor<span style="color: #002200;">&#93;</span>,
                                   <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIColor colorWithHexString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;6f778b&quot;</span><span style="color: #002200;">&#93;</span> CGColor<span style="color: #002200;">&#93;</span>,
                                   <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIColor colorWithHexString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;5b657d&quot;</span><span style="color: #002200;">&#93;</span> CGColor<span style="color: #002200;">&#93;</span>,
                                   <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
        normalBackground.locations <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSArray</span> arrayWithObjects<span style="color: #002200;">:</span>
                                      <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>,
                                      <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #2400d9;">0.5</span><span style="color: #002200;">&#93;</span>,
                                      <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #2400d9;">0.51</span><span style="color: #002200;">&#93;</span>,
                                      <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span>,
                                      <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">return</span> self;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>




<p>Next we need to add a UIView to our main view in Interface Builder and set the class property to our new custom GradientControl:</p>

<p><a href="http://purpledragonsoftware.com/blog/wp-content/uploads/2012/01/gradient-control-interface-builder.png" rel="lightbox[141]"><img src="http://purpledragonsoftware.com/blog/wp-content/uploads/2012/01/gradient-control-interface-builder-300x267.png" alt="Setting the custom class property to GradientControl in Interface Builder" title="Setting custom class" width="300" height="267" class="alignnone size-medium wp-image-179" /></a></p>

<p>Now if we run it in the simulator we can see our new shiny rounded gradient control:</p>

<p><a href="http://purpledragonsoftware.com/blog/wp-content/uploads/2012/01/gradient-control-first-pass.png" rel="lightbox[141]"><img src="http://purpledragonsoftware.com/blog/wp-content/uploads/2012/01/gradient-control-first-pass-200x300.png" alt="Screenshot showing the application so for in the iOS simulator" title="Initial app showing gradient control" width="200" height="300" class="alignnone size-medium wp-image-181" /></a></p>

<p>Although this new component responds to events and triggers any actions that you assign it doesn&#8217;t give any visual feedback to taps. This can be solved by creating a second gradient layer and swapping the layers when the highlight value changes:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;QuartzCore/QuartzCore.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> GradientControl <span style="color: #002200;">:</span> UIControl
<span style="color: #002200;">&#123;</span>
    CAGradientLayer <span style="color: #002200;">*</span>normalBackground;
    CAGradientLayer <span style="color: #002200;">*</span>highlightBackground;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> GradientControl
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span> initWithCoder<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSCoder</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>aDecoder
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super initWithCoder<span style="color: #002200;">:</span>aDecoder<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        self.backgroundColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor clearColor<span style="color: #002200;">&#93;</span>;
&nbsp;
        normalBackground <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CAGradientLayer layer<span style="color: #002200;">&#93;</span>;
        <span style="color: #11740a; font-style: italic;">// setup normal background...</span>
&nbsp;
        highlightBackground <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CAGradientLayer layer<span style="color: #002200;">&#93;</span>;
        <span style="color: #11740a; font-style: italic;">// setup highlight background...</span>
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">return</span> self;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> setHighlighted<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>aHighlighted
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">BOOL</span> oldHighlighted <span style="color: #002200;">=</span> self.highlighted;
    <span style="color: #002200;">&#91;</span>super setHighlighted<span style="color: #002200;">:</span>aHighlighted<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>oldHighlighted <span style="color: #002200;">==</span> aHighlighted<span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">return</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>aHighlighted<span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>self.layer replaceSublayer<span style="color: #002200;">:</span>normalBackground with<span style="color: #002200;">:</span>highlightBackground<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">else</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>self.layer replaceSublayer<span style="color: #002200;">:</span>highlightBackground with<span style="color: #002200;">:</span>normalBackground<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>




<p>Now when we tap the control the background seamlessly switches to the highlighted background:</p>

<p><a href="http://purpledragonsoftware.com/blog/wp-content/uploads/2012/01/gradient-control-touch-response.png" rel="lightbox[141]"><img src="http://purpledragonsoftware.com/blog/wp-content/uploads/2012/01/gradient-control-touch-response-200x300.png" alt="Screenshot showing the updated gradient control responding to touch events" title="Updated app with tapped gradient control" width="200" height="300" class="alignnone size-medium wp-image-180" /></a></p>

<p>The last thing to do is to add some setters to change the background colours and the border. With these we can easily create a range of gradient controls:</p>

<p><a href="http://purpledragonsoftware.com/blog/wp-content/uploads/2012/01/final-app.png" rel="lightbox[141]"><img src="http://purpledragonsoftware.com/blog/wp-content/uploads/2012/01/final-app-200x300.png" alt="" title="Final app showing different controls" width="200" height="300" class="alignnone size-medium wp-image-176" /></a></p>

<p>The full code with examples can be found on <a href="https://github.com/stringbean/blog-code">GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://purpledragonsoftware.com/blog/2012/01/custom-gradient-controls-for-ios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trangia adapter for the Optimus Nova stove</title>
		<link>http://purpledragonsoftware.com/blog/2010/07/trangia-adapter-for-the-optimus-nova-stove/</link>
		<comments>http://purpledragonsoftware.com/blog/2010/07/trangia-adapter-for-the-optimus-nova-stove/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 00:28:32 +0000</pubDate>
		<dc:creator>stringbean</dc:creator>
				<category><![CDATA[Camping Equipment]]></category>
		<category><![CDATA[trangia optimus nova stove cooking review]]></category>

		<guid isPermaLink="false">http://purpledragonsoftware.com/blog/?p=62</guid>
		<description><![CDATA[When I started camping for slaloms and other paddling events I needed a new stove and after looking at a<a href="http://purpledragonsoftware.com/blog/2010/07/trangia-adapter-for-the-optimus-nova-stove/" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p><a href="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/nova-stove.jpg" rel="lightbox[62]"><img class="size-thumbnail wp-image-74 alignleft" title="The unmodified Optimus Nova+ stove" src="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/nova-stove-300x200.jpg" alt="Optimus Nova+ stove" width="300" height="200" /></a>When I started camping for slaloms and other paddling events I needed a new stove and after looking at a number of options (spirit burners, gas stoves etc) I settled on the Optimus Nova+. Why did I choose the Nova+? It produces a similar heat output to a gas stove and burns petrol which can be bought almost anywhere.</p>
<p>After using the Nova+ plus for a while I came to realise that the aluminum windshield that is supplied with the stove was tricky to use, not very sturdy and not that effective. I liked the stove and was impressed by its performance but something had to be done about the windshield.</p>
<p>While looking for a spares kit to service my stove I noticed that Optimus manufacture an adapter to mount the burner of a Nova/Nova+ stove inside the windshield of a Trangia. I had used Trangia stoves in the past and knew that they were sturdy, lightweight and compact. When a local camping store had a Trangia 25-2UL (ultra-light, large with kettle) on sale I decided to buy one and try the adapter.<span id="more-62"></span></p>
<h2>Fitting the adapter</h2>
<ol>
<li>Remove the fuel line from the stove.</li>
<li>Turn the stove upside down and unscrew the nut that holds the burner to the body.</li>
<li>Remove the body (leave the priming wick attached).</li>
<li>Fit the adapter clip and priming cup then secure using the nut removed earlier. I had to enlarge the hole on the adapter as it was too small to fit on my burner.</li>
<li>Reattach the fuel line.</li>
</ol>
<p><a href="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/fitting-step-1.jpg" rel="lightbox[62]"><img class="alignnone size-thumbnail wp-image-100" title="Remove the fuel  line from the stove" src="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/fitting-step-1-150x150.jpg" alt="Nova+ stove after removing the fuel line" width="150" height="150" /></a><a href="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/fitting-step-2.jpg" rel="lightbox[62]"><img class="alignnone size-thumbnail wp-image-102" title="Remove the Nova+  body from the burner" src="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/fitting-step-2-150x150.jpg" alt="Nova+ stove after removing the body" width="150" height="150" /></a><a href="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/fitting-step-3.jpg" rel="lightbox[62]"><img class="alignnone size-medium wp-image-103" title="Fit the adapter and  priming cup to the burner" src="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/fitting-step-3.jpg" alt="Nova+ stove with the Trangia adapter attached" width="200" height="300" /></a></p>
<p>The adapted burner can now be dropped into the the hole where the Trangia burner goes and the fuel line threaded through the hole that the Trangia gas adapter uses.</p>
<h2>Testing the adapter and final thoughts</h2>
<p>Now that the adapter was fitted it was time to see how it performs by boiling a kettle. The Trangia base was much more stable than the Nova+ base and the built in windshield was significantly more effective than the flimsy foil one. The only downside to the Trangia/Nova+ hybrid is that the burner is recessed in the base of the Trangia windshield which makes it a bit tricky to light the stove. This is only a minor downside and is outweighed by the benefits of the Trangia base.<a href="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/trangia-nova-hybrid.jpg" rel="lightbox[62]"><img class="alignright size-thumbnail wp-image-92" title="Testing the Trangia adapter" src="http://purpledragonsoftware.com/blog/wp-content/uploads/2010/07/trangia-nova-hybrid-200x300.jpg" alt="Testing the Trangia adapter" width="200" height="300" /></a></p>
<p>The Trangia/Nova+ hybrid combines some of the best features of both stoves and should serve me well for the foreseeable future. Carrying the Trangia burner as well as the Nova+ burner will also add the ability to burn alcohol based fuels (methylated spirits) as well petrolium based fuels (petrol, diesel etc) making it even easier to find fuel while travelling.</p>
<p>My recommendation: If you have an Optimus Nova or Nova+ and an old Trangia knocking around then this is a cheap upgrade that will improve your stove. If you don&#8217;t already have a Trangia then it is an expensive upgrade but still worthwhile.</p>
]]></content:encoded>
			<wfw:commentRss>http://purpledragonsoftware.com/blog/2010/07/trangia-adapter-for-the-optimus-nova-stove/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Welcome to the blog</title>
		<link>http://purpledragonsoftware.com/blog/2010/05/welcome-to-the-blog/</link>
		<comments>http://purpledragonsoftware.com/blog/2010/05/welcome-to-the-blog/#comments</comments>
		<pubDate>Thu, 27 May 2010 22:00:24 +0000</pubDate>
		<dc:creator>stringbean</dc:creator>
				<category><![CDATA[Random Musings]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[site]]></category>
		<category><![CDATA[welcome]]></category>

		<guid isPermaLink="false">http://purpledragonsoftware.com/blog/?p=4</guid>
		<description><![CDATA[Welcome to my new blog! I&#8217;ve decided to try and join the 21st century and enter the blagosphere. I&#8217;ve had<a href="http://purpledragonsoftware.com/blog/2010/05/welcome-to-the-blog/" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Welcome to my new blog! I&#8217;ve decided to try and join the 21st century and enter the blagosphere. I&#8217;ve had a shared hosting web account sitting round pretty much idle for  a couple of years and sorting out a website for a paddling friend has  spurred me into action.<span id="more-4"></span></p>
<p>So what can we expect from this blog? Well to be quite honest I&#8217;m not too sure. I&#8217;ve got a few programming and electronics projects in the pipeline that I&#8217;m hoping to get time to work on in the near future. Then there are my paddling escapades which at the moment centre around me trying to stay upright in a C1 slalom boat at HPP! And finally there might be some random musings about life, the universe and everything&#8230;</p>
<p>Expect things to change as I sort out a final theme and find my way around WordPress. Hopefully things will settle down quickly and this blog will develop into something that everyone can enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://purpledragonsoftware.com/blog/2010/05/welcome-to-the-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

