<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>madeFM | creating iPhone Apps made in Germany.</title><generator>Tumblr (3.0; @madefm)</generator><link>http://blog.madefm.com/</link><item><title>iOS DevCorner: FMMoveTableView</title><description>&lt;p&gt;For my current project I need to move rows in a UITableView (without being in an edit mode) simply by tap and hold an appropriate row - like in the &lt;a href="http://www.realmacsoftware.com/clear/"&gt;Clear app&lt;/a&gt;.&lt;/p&gt;

&lt;p style="text-align:center; margin: 25px 0;"&gt;&lt;img src="http://madefm.com/media/blog/FMMoveTableViewSampleImage.png"/&gt;&lt;/p&gt;

&lt;h2&gt;The Files&lt;/h2&gt;
&lt;p&gt;After struggling a few hours I came up with a solution by creating a UITableView subclass that I&amp;#8217;d like to share. So I&amp;#8217;ve created a sample project, added some (hopefully useful) comments and pushed it into a &lt;a href="http://cl.ly/FMED" style="font-weight:bold; color:#E2A94A; text-decoration:underline;"&gt;github Repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve put it under BSD license, so feel free to use it in your project. Please contact me  (&lt;a href="http://twitter.com/FlorianMielke"&gt;@FlorianMielke&lt;/a&gt;), if you have any suggestions for improving the code.&lt;/p&gt;


&lt;p style="margin-top:40px;"&gt;Take care,&lt;br/&gt;
Florian&lt;/p&gt;</description><link>http://blog.madefm.com/post/20010953414</link><guid>http://blog.madefm.com/post/20010953414</guid><pubDate>Tue, 27 Mar 2012 17:54:06 +0200</pubDate></item><item><title>iOS DevCorner: Attaching an info panel to a UIScrollViewIndicator like in the Path 2 app</title><description>&lt;p&gt;Last week the new &lt;a href="http://path.com"&gt;Path 2&lt;/a&gt; app was released with a bunch of great UI tweaks, which I promise we will definitely see in other apps really soon.&lt;/p&gt;
&lt;p&gt;One of the most impressive one to me was the info panel attached to the scroll view indicator which appears as you begin scrolling and disappears after the scroll view stops.&lt;/p&gt;
&lt;p style="text-align:center; margin: 25px 0;"&gt;&lt;img src="http://26.media.tumblr.com/tumblr_lvzgtccQG51qbj1h6o1_500.png"/&gt;&lt;/p&gt;
&lt;p&gt;In contrast to the existing table view sections the info panel approach is non-persistent. It allows you to temporarily group data in a table view. Therefore it is not qualified to simply replace every table view section in your app, but it could be a good alternative or even an addition in some cases. So let&amp;#8217;s dive into one possible solution I&amp;#8217;ve figured out how to create an attached info panel.&lt;/p&gt;
&lt;h2&gt;The Basics&lt;/h2&gt;
&lt;p&gt;A &lt;code&gt;UIScrollViewIndicator&lt;/code&gt; is the top most subview of a &lt;code&gt;UIScrollView&lt;/code&gt; or of one of it&amp;#8217;s subclasses, e.g. a &lt;code&gt;UITableView&lt;/code&gt;. The indicator itself is simply an &lt;code&gt;UIImageView&lt;/code&gt;. Unless you are not scrolling it&amp;#8217;s alpha is 0 and therefore not visible - but it&amp;#8217;s there right from the beginning. When the user scrolls to the top or bottom  and drags it&amp;#8217;s finger a little further – like a rubber band - the size of the indicator shrinks until it finally became a dot.&lt;/p&gt;
&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;The basic idea is to add the info panel&amp;#8217;s root layer as a sublayer to the indicator&amp;#8217;s root layer. With that, the info panel scrolls smoothly and stays in parallel to the indicator  automatically. In the case were the scroll view hit the edges, we want the info panel to stay visible at the top or bottom of the screen, so we need to do some extra calculation to let it stay centered.&lt;/p&gt;
&lt;h2&gt;The Code: Interface&lt;/h2&gt;
&lt;p&gt;Here we just need four ivars which are quite self-explanatory:&lt;/p&gt;
&lt;pre&gt;
#import &amp;lt;UIKit/UIKit.h&amp;gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;
#import &amp;lt;QuartzCore/QuartzCore.h&amp;gt;

@interface FMInfoPanelViewController : UIViewController &lt;uiscrollviewdelegate&gt;
{
	UIScrollView *scrollView;
	UIView *infoPanel;
	CGSize initialSizeOfInfoPanel;
	CGFloat initialHeightOfScrollIndicator;
}
@end&lt;/uiscrollviewdelegate&gt;&lt;/pre&gt;
&lt;h2&gt;The Code: Implementation&lt;/h2&gt;
&lt;p&gt;In our implementation we first create an &lt;code&gt;UIImageView&lt;/code&gt; which simply acts as a background of our info panel. After that we create the info panel itself with a negative x-origin so it will appear left to the scroll indicator.&lt;/p&gt;
&lt;pre&gt;
#pragma mark - 
#pragma mark View lifecycle

- (void)viewDidLoad
{
	CGRect viewFrame = [[self view] frame];

	scrollView = [[UIScrollView alloc] initWithFrame:viewFrame];
	[scrollView setDelegate:self];
	[scrollView setContentSize:CGSizeMake(viewFrame.size.width, viewFrame.size.height * 4)];
	[[self view] addSubview:scrollView];
	
	UIImageView *backgroundImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"infoPanel.png"]];
	initialSizeOfInfoPanel = [backgroundImage frame].size;

	infoPanel = [[UIView alloc] initWithFrame:CGRectMake(initialSizeOfInfoPanel.width * (-1), 0, initialSizeOfInfoPanel.width, initialSizeOfInfoPanel.height)];
	[infoPanel addSubview:backgroundImage];
	[backgroundImage release], backgroundImage = nil;
}
&lt;/pre&gt;
&lt;p style="margin-top:40px;"&gt;&lt;strong&gt;scrollViewWillBeginDragging&lt;/strong&gt;: When the user starts scrolling we check whether the info panel is currently visible or not. If not we will add it&amp;#8217;s root layer as as sublayer of the scroll indicators root layer. One important thing I&amp;#8217;ve figured out is to set the background color of our info panels layer to the same as the scroll indicator&amp;#8217;s root layer. Otherwise the scroll indicator wont be translucent anymore.&lt;/p&gt;
&lt;pre&gt;#pragma mark -
#pragma mark Scroll view delegate

- (void)scrollViewWillBeginDragging:(UIScrollView *)aScrollView
{
	if (![infoPanel superview]) 
	{
		UIView *indicator = [[aScrollView subviews] lastObject];
		CGRect indicatorFrame = [indicator frame];
		initialHeightOfScrollIndicator = indicatorFrame.size.height;
		
		[[infoPanel layer] setBackgroundColor:[[indicator layer] backgroundColor]];
		[[indicator layer] addSublayer:[infoPanel layer]];

		&lt;span style="font-style:italic; color:green;"&gt;// Center the info panel&lt;/span&gt;
		CGRect infoPanelFrame = [infoPanel frame];
		infoPanelFrame.size = initialSizeOfInfoPanel;
		infoPanelFrame.origin.y = indicatorFrame.size.height / 2 - infoPanelFrame.size.height / 2;
		[infoPanel setFrame:CGRectIntegral(infoPanelFrame)];
	}
}&lt;/pre&gt;
&lt;p style="margin-top:40px;"&gt;&lt;strong&gt;scrollViewDidScroll&lt;/strong&gt;: As our info panel is already attached to the scroll indicator we can avoid a lot of unnecessary calculations when the scroll view just scrolls within it&amp;#8217;s content area. Though we have to do some work when we reach the top or bottom of the screen:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;When the scroll indicator starts shrinking we have to calculate the new center of our info panel.&lt;/li&gt;
&lt;li&gt;When the scroll indicator&amp;#8217;s height became less that the info panel&amp;#8217;s height and we are on the top of the screen we don&amp;#8217;t need to do any extra work as the info panel should stay at it&amp;#8217;s current position.&lt;/li&gt;
&lt;li&gt;When we are at the bottom of the screen we need to calculate a negative y-origin so the info panel will stay at the bottom while the scroll indicator continues to shrink.&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
	UIView *indicator = [[aScrollView subviews] lastObject];
	CGRect indicatorFrame = [indicator frame];

	&lt;span style="font-style:italic; color:green;"&gt;// We are somewhere at the edge (top or bottom)&lt;/span&gt;
	if (indicatorFrame.size.height &amp;lt; initialHeightOfScrollIndicator)
	{
		CGRect infoPanelFrame = [infoPanel frame];

		&lt;span style="font-style:italic; color:green;"&gt;// The indicator starts shrinking, so we need to adjust our info panel's y-origin to stays centered&lt;/span&gt;
		if (indicatorFrame.size.height &amp;gt; infoPanelFrame.size.height + 2) 
		{
			infoPanelFrame.origin.y = (indicatorFrame.size.height / 2) - (infoPanelFrame.size.height / 2);
		}
		&lt;span style="font-style:italic; color:green;"&gt;// We are at the bottom of the screen and the indicator is now smaller than our info panel&lt;/span&gt;
		else if (indicatorFrame.origin.y &amp;gt; 0)
		{
			infoPanelFrame.origin.y = (infoPanelFrame.size.height - indicatorFrame.size.height) * (-1);
		}

		[infoPanel setFrame:infoPanelFrame];
	}
}&lt;/pre&gt;
&lt;p style="margin-top:40px;"&gt;&lt;strong&gt;scrollViewDidEndScrollingAnimation&lt;/strong&gt;: As we are good citizens we will remove our info panel when the scroll view stops scrolling.&lt;/p&gt;
&lt;pre&gt;- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
	[infoPanel removeFromSuperview];
}&lt;/pre&gt;
&lt;h2&gt;The Additions&lt;/h2&gt;
&lt;p&gt;The Path 2 app has some nice additional animations to fade in and fade out the info panel. It also stays visible for a second after the scroll view has stopped scrolling so the user knows if he scrolled to the right position.&lt;/p&gt;
&lt;h2&gt;The Files&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ve created a public &lt;a href="https://gist.github.com/1437123"&gt;github gist&lt;/a&gt; and &lt;a href="http://cl.ly/CNTF"&gt;Xcode sample project&lt;/a&gt; so you can download the source files.&lt;/p&gt;
&lt;p&gt;I hope this solution gives you an idea of how to implement this great UI approach to your app to increase the user experience. If you have any suggestions on how to solve it better, more easily or in a completely different way, please contact me &lt;a href="http://twitter.com/#!/FlorianMielke/"&gt;@FlorianMielke&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Take care,&lt;br/&gt;
Florian&lt;/p&gt;</description><link>http://blog.madefm.com/post/13817640556</link><guid>http://blog.madefm.com/post/13817640556</guid><pubDate>Tue, 06 Dec 2011 07:21:00 +0100</pubDate></item><item><title>WorkTimes 3.0 first test flight begins</title><description>&lt;p&gt;After months of development and many ups and downs during that time — you have no idea how complex time tracking is — I&amp;#8217;m very excited to announce the start of the WorkTimes 3.0 test flight today.&lt;/p&gt;
&lt;p style="margin:30px auto; text-align:center;"&gt;&lt;img src="http://media.tumblr.com/tumblr_lppry7fwrl1qbx8q4.png"/&gt;&lt;/p&gt;
&lt;p&gt;WorkTimes 3.0 is the result of over one year of experiences being in the App Store and countless feedbacks from customers. It is definitely the most extensive update since Version 1.0.&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s new&lt;/h2&gt;
&lt;p&gt;Here is a small abstract of the top new features in WorkTimes 3.0:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Completely redesigned from the ground up&lt;/li&gt;
&lt;li&gt;Completely new user interface&lt;/li&gt;
&lt;li&gt;Manual overtime (comp. time) records are integrated into work time records to provide a much better user experience&lt;/li&gt;
&lt;li&gt;Unified Days: Multiple records on the same day are combined into one record&lt;/li&gt;
&lt;li&gt;Support for multiple user accounts with individual settings (target time, email adresse for export, …&lt;/li&gt;
&lt;li&gt;Analytics for week, month and year — &lt;i&gt;unbelievable&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Two new kinds of tags (numeric and currency) to be more flexible to track what you need, e.g. your vacation over the year, overtime pay — no more limits&lt;/li&gt;
&lt;li&gt;Overtime is displayed per day&lt;/li&gt;
&lt;li&gt;Fix starting time&lt;/li&gt;
&lt;li&gt;Time zone support &lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;And there are still a lot of features waiting for the upcoming versions.&lt;/p&gt;
&lt;h2&gt;How to become a beta tester&lt;/h2&gt;
&lt;p&gt;Please fill out our &lt;a href="http://bit.ly/ec8Hwh"&gt;TestFlight Form&lt;/a&gt; to be added to the beta list. The first version will be available till the end of this week.&lt;/p&gt;
&lt;p&gt;Please only subscribe if you are willed to intensively test all beta versions and provide comprehensive feedback to &lt;a href="mailto:beta@madefm.com"&gt;beta@madefm.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The beta version will be provided as a completely separate install. None of your productive data and installed version will be affected.&lt;/p&gt;
&lt;p style="margin-top:30px;"&gt;Happy testing,&lt;br/&gt;&lt;b&gt;Florian&lt;/b&gt;&lt;/p&gt;</description><link>http://blog.madefm.com/post/8734135943</link><guid>http://blog.madefm.com/post/8734135943</guid><pubDate>Wed, 10 Aug 2011 16:33:00 +0200</pubDate></item></channel></rss>

