Tuesday 25 December 2012

Rails helpers you should be familiar with

AssetTagHelper

- helps you link html page with various assets as javascripts, stylsheets, images...
- useful if you have assets saved on different servers

javascript_include_tag(*sources)

- creates a script tag for each of the provided sources
- tarts from public/javascripts
- uses javascript_path to calculate the path to the javascript file

stylesheet_link_tag(*sources)

- creates a stylesheet link tag for each of the provided sources
- starts from public/stylesheets
- stylesheet_path caluculates locat

image_tag(source, options = {})

- creates a image tag for the provided image location
- image_path caluculates location
- aditional HTML params(align...) can be passed by using options hash

CaptureHelper

- very useful for reusing page parts at different locations by using yield

content_for(name, &block)
- saves the content of the block and provides it for later usage
- useful for action menus or similar components used at different
places but with similar functions

content_for?(name)

- checks weather we'll get any context by using content_for 

DateHelper

- useful for creating select tags for different date combos(full date, only year, time ...)
by using methods like select_date, select_time ...
- includes distance calculation methods like distance_of_time_in_words:
  distance_of_time_in_words(Time.now, Time.now + 5.minute) => "5 minutes" 

FormHelper

- helps with craeating forms closely related to Active Record models linked with a view

form_for(record, options = {}, &proc)

- creates a form and a scope around a specific model object that is used as a source for field data.
- accepts params :url (location where form is submitted to), :html (standard attributes) and :builder (custom form builder e.g. Formtastic)
- uses automated resource identification to configure submit location
- default protection from CSRF attacks
- support for multiple objects update by using square bracket notation => form_for "user[]" do ...

fields_for(record_name, record_object = nil, options = {}, &block)

- creates a scope arround a specific model object without creating tags
form_for @user do |f|
.....
fields_for @user.settings do |s| => params[:user][:settings]

field builders

check_box, email_field, file_field, hidden_field, label, number_field, password_field, radio_button, range_field, search_field, submit, telephone_field, text_area and text_field 

FormTagHelper

- same results as FormHelper but without a link to Active Model instance

NumberHelper

- helps with formatting numbers understandable to user

number_to_currency(number, options = {})

- number_to_currency(12345.60) => $ 12,345.60

number_to_human_size(number, options = {})

- number_to_human_size(1234) => 1.2 KB

 

TagHelper

content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) 

- programmatically creates a HTML block by using provided tag name and content
- you can also pass a block to create more complex content

tag(name, options = nil, open = false, escape = true)  

-creates tag programmatically

 

TextHelper


pluralize - attempts to pluralize singular world

 

UrlHelper

- methods for generating links

button_to(name, options = {}, html_options = {})

- creates a form submit button directed at the URL from options parameter
- used for all resource modifier actions to prevent unwanted changes

link_to(*args, &block)

- creates a link for the given name and options
- options are processed by url_for method which returns URL for the provided options

Tuesday 18 December 2012

Rails attribute serialization

Switching to Postgres after working for over two years on Hbase is quite a change. The ability to use ActiveRecord feels like getting a nuke. Searches, orders, associations, you name it. But on the other hand, one of the things that felt missing was serialization of which I got so accustomed. It just felt wrong to create separate table for users settings. Why not just store it in the User table?!

Well, Active Record has an option for that. Attributes can be marked as serializable and stored in desired format in the database. Default format is YAML, but you can pass Array, Hash or Class of your own. I'll use Hash:
# model
class User < ActiveRecord::Base
  serialize :settings, Hash
end

# controller
def create
  @user = User.new(params[:user])
  ......
end
Unless a value has already been set for the settings attribute, this won't work since its not initialized.
We can fix that with after_initialize callback:
# initialization callback
def after_initialize
  self.settings ||= {} 
end
Another thing we have to do is to make the form add settings parameter around the items we want to set. We are creating a new object with mass assignment so we need to tell the new method that these attributes are part of the settings hash not of the User model. For this this purpose fields_for helper comes in handy:
# form view
<%= f.fields_for :settings do |setting| %>
  Send newsletter <%= setting.check_box :send_newsletter %>
<% end %>
When we save the user and look in the database we should see serialized settings parameter saved as settings: {"send_newsletter"=>"1"} .
I think this is quite useful for avoiding creating all new table,  joins and so on....

Wednesday 21 November 2012

Pinterest styled list for Android

Pinterest is more and more popular and many apps use its "masonry" pattern. I used the same pattern in my last project and must say it wasn't as easy job as it looked at first. Here's what I'd been doing...

At first logical solution was to use vertical LinearLayouts inside a ScrollView - easy and simple.
All I had to add is code which adds elements proportionately in each LinearLayout.
<ScrollView>
<LinearLayout
   orientation="horizontal">

   <LinearLayout
     android:layout_weight="0.5"
     orientation="vertical">

   <LinearLayout
     android:layout_weight="0.5"
     orientation="vertical">

</LinearLayout>
</ScrollView>
This worked fine at the beginning but when I added more than 100 items, as expected, app started to crash. Well if you think about it it was obvious, with this approach we don't use recycling so layout constantly had 100 items filled with layouts, pictures, formatted text..

Second solution I thought of was two synchronized ListViews. They have internal caching so all I had to do is synchronize them.
<LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:paddingLeft="10dp"
    android:paddingRight="10dp">

    <ListView
        android:id="@+id/list_view_left"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:paddingRight="5dp"
        android:scrollbars="none" >
    </ListView>

    <ListView
        android:id="@+id/list_view_right"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:paddingLeft="5dp"
        android:scrollbars="none" >
    </ListView>

</LinearLayout> 
My first attempt was to add OnTouchListener which will pass the touch event to the opposite list and OnScrollListener which will update first opposite child.
listOne.setOnTouchListener(new OnTouchListener() {
    @Override
       public boolean onTouch(View arg0, MotionEvent arg1) {
       listTwo.dispatchTouchEvent(arg1);
       return false;
    }
});
listOne.setOnScrollListener(new OnScrollListener() {
   @Override
   public void onScrollStateChanged(AbsListView arg0, int arg1) {
   }
   @Override
   public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
          if (l1.getChildAt(0) != null) {
              Rect r = new Rect();
              l1.getChildVisibleRect(l1.getChildAt(0), r, null);
              l2.setSelectionFromTop(l1.getFirstVisiblePosition(), r.top);
          }
    }
});  
Well this seemed as good solution. It was working with single list, scrolling was smooth so adding the same code to the opposite list should work fine but unfortunately it didn't. They ware both synced on first visible child so when one would disappear the other would automatically be positioned to match the new one. This made scrolling feel quite unnatural so other solution had to be found.

It occurred to me that I can just calculate distances from top of both elements, subtract one from another and add offset of the current element. Hmmm, well let's be more precise it took me a while get to this calculation but if you draw an example yourself, you'll see its just logical.
Source can be found on Github  
This solution works fine. I have few bugs to fix, simplify the code - make it more simple to use and that should be it. 
Still it bothers me if this can be implemented by using BaseAdapter and AdapterView. I'll  have an option to use adapters caching and what remains is child positioning. Well, I'll give it a try as soon as I find spare time...

Friday 6 July 2012

List of Android Adapters

Month ago I first saw ResourceCursorAdapter being used in Android development.
That gave me enough curiosity to summarize them all in a single place.


There are several types which differ by data source and manipulation complexity available to the user. Lets start...

BaseAdapter
Simple adapter implementation used for ListView. You provide data by overriding required methods that provide elements for the list. Mostly used for simple list implementations.

SimpleAdapter 
Very useful adapter that allows us to map data to elements in the layout file. You provide a grid (two same sized arrays) which tells which element goes into which place and map that contains all the data needed for this grid to know what to put where.

ArrayAdapter
For me less convenient than the SimpleAdapter since default behavior is to map String array elements to single text field. You can override it and provide an array of complex object which have data to populate more complex rows.

SimpleCursorAdapter
An easy adapter to map columns from a cursor to elements defined  in the layout file. You can specify which columns you want, which views you want to display the columns, and the layout file that defines the appearance of these views.


CursorAdapter
More sofisitcated implementation of the SimpleCursorAdapter which is abstract so its up to you
to create views with cursor providing you the data from database.

ResourceCursorAdapter
Very similar to CursorAdapter. Doesn't have a newView method which makes it more appropriate
for not so complex views. 

SpinnerAdapter
Haven't used this one that much but from what I've seen enables you to define two views, one with data and the second dropdown with choices.

SimpleCursorTreeAdapter
The following two are my most favorite. They allow us to define list elements together with the groups they belong in. Very convenient for situations where you need list with grouped data. You provide both child and group views with appropriate data binding

CursorTreeAdapter
Same as previous but with more liberty and requirements. Better for complex lists.

HeaderViewListAdapter
ListAdapter used when a ListView has header views. This ListAdapter wraps another one and also keeps track of the header views and their associated data objects.

WrapperListAdapter
Haven't seen this one before. Haven't seen any examples but it seems it wraps another list adapter. Strange...

Well that's all I thing....
Now I have them all in single place so I don't have to look around. Sweet :)


Friday 29 June 2012

Installing Jelly Bean on Galaxy Nexus

As you know Google unveiled Android 4.1 Jelly Bean which looks amazing. Official ROM was leaked to the public and is now available for download. If you have a rooted Galaxy Nexus and if you want to play around with the latest Android (on your own responsibility) follow the instructions bellow. 



First of all, you need a ClockworkMod recovery that you can install the usual way, but also through the ROM manager. The procedure will delete personal information, but not the contents of internal memory.

  1. Download Jelly Bean ROM
  2. Move it to the phone's internal memory.
  3. Turn off your phone.
  4. Start the phone in recovery mode.
  5. Once the menu appears, enter your organization and recovery "install zip from SD card"
  6. Select Wipe & factory reset.
  7. Flash the ROM.
  8. Select Reboot System.

And there you have it ... Jelly Bean on Galaxy Nexus

Friday 18 May 2012

Using RVM with different versions of Rails on Mac OSX

I had to use both jRuby and Ruby with different versions of Rails on the same machine which turned out to be quite a frustration. I've heard about RVM which separates Ruby environments together with their gems from one another. I decided to give it a shot...
RVM installation (stable version)
  1. first lets install the RVM
    curl -L get.rvm.io | bash -s stable 
  2. after installation we'll have to reload the console and run:
    source ~/.rvm/scripts/rvm
  3. test if everything was OK
    type rvm | head -n 1 
    to get the message rvm is a function
Ruby installation 

I will be using jRuby 1.6.5 and Ruby 1.9.3 so we need to install those two:
rvm install  1.6.5
rvm install  1.9.3 
After installations finish, run rvm list to get the list of installed rubies.
I will use jRuby and set it as default as I use it most of the time:
rvm use 1.6.5 --default

Rails installation

First we'll need Gemsets. They can be regarded as folders with separate ruby setups, gems and irb, all separate and self-contained - from the system, and from each other.
Lets create one for the Rails we require 2.3.8
rvm gemset create rails238
rvm use 1.6.5@rails238

To install rails and remaining gems we can use gem install but since I use geminstaller we can just run this gem and it does the job for us.
gem install geminstaller
geminstaller

Before we can start anything we have to set path for our new jRuby in .profile and refresh it
with source ~/.profile.
At the end we can override rvmrc to load this gemset automatically:
rvm --rvmrc --create 1.6.5@rails238

For Rails 3.2, which I will use with Ruby,  the gemset stuff is same as before except I'll use bundle install.

We'll these are my notes for RVM installation. Off to checkout Pry, heard it's way better than IRB....

Tuesday 17 April 2012

Android: Parsing JSON with Generics

Parsing JSON in Android is quite a common task but as project grows this can become quite messy if not done properly at the beginning.
I will create a simple function which parses JSON by passing a expected class type and getting the instance of the same class if request is successful.
We will achieve this by using Java Generics. From what I've seen so far, many people run away from this feature but in this case they are just the right tool for the job.
So here's how the stuff should look like:
/**
 * Converts recieved JSON into passed type
 * @param url - address to which are we posting
 * @param requestObject - post data
 * @param responseType - type of the response we are expecting
 * @return - instance of the class
 * @throws Exception - use more precise exceptions
 */
public < T extends Response > T simplePostExample(String url, 
  Object requestObject, Class responseType) throws Exception {
                
  // standard post request with json content
  HttpPost request = new HttpPost(url);
  request.setHeader("Accept", "application/json");
  request.setHeader("Content-type", "application/json");
                
  // converting post data to json
  String json = new Gson().toJson(requestObject);
  StringEntity requestEntity = new StringEntity(json);
  request.setEntity(requestEntity);
                
  // executing request
  HttpResponse httpResponse = httpClient.execute(request);
  HttpEntity entity = httpResponse.getEntity();

  checkResponse(httpResponse, entity);

  if (entity != null) {
   InputStream content = entity.getContent();
   Reader reader = new InputStreamReader(content);
                        
   // convert response to new instance of the expected class
   T object = new Gson().fromJson(reader, responseType);
   return object;
  } else {
   throw new Exception("Something went wrong…");
  }
 }
        
 // check if everything is as it should be
 private void checkResponse(HttpResponse httpResponse, HttpEntity entity)
   throws Exception {
  int statusCode = httpResponse.getStatusLine().getStatusCode();
  if (statusCode != HttpStatus.SC_OK)
   throw new Exception("Something went wrong…");

  Header contentType = entity.getContentType();
  if (contentType == null
    || !contentType.getValue().startsWith("application/json"))
   throw new Exception("Something went wrong…");
 }

All responses inherit Response class which can also be useful for storing data that all responses have ( status, message...). This is just a quick example, but can later be extended to use more features like other http requests, credentials and etc...

Monday 12 March 2012

Android layout for grouping views in iOS style

Although this is default for iOS (UITableView) its often used in Android also,
so I decided to write a simple library for this purpose. This is the first edition with only plain, edit text and few basic options so everyone is free to participate!
GroupedTextView on Github

Friday 3 February 2012

Installing subclipse on Mac OSX Lion

I've just installed Subclipse SVN plugin version 1.8.x. but as always there ware problems. This time it was JavaHL library. Default instalation from openCollabNet is 1.6.7 which isn't compatible with this version of Subclipse:

Subclipse Version SVN/JavaHL Version
1.8.x 1.7.x
1.6.x 1.6.x
1.4.x 1.5.x

One option would be to revert to previous version which I didn't quite like.
Second is "unrecommended" installation from MacPorts.
Instalation goes ok but with few tweeks! Just run the following command(s) and you are set to go!

sudo port install subversion-javahlbindings

If you have problems with updating from previous version:
sudo port clean subversion-javahlbindings
sudo port selfupdate
sudo port upgrade outdated


If you have problems with updating db64:
sudo port clean -f --all db46
sudo port selfupdate
sudo port install db46

Wednesday 4 January 2012

UITableView introduction

I've been playing with UITableView for a while so I've decided to write this tutorial in which I will cover everything I've used so far, from the basic data source to the the custom table cell. For the final goal of this tutorial I will use my favorite task management app - Wunderlist which is practically based on UITableView and it can serve as a great example! It's a great app and I recommend it to all! Code bellow is already on Github. So lets start…

Unlike in Android or JME, where you specify what to display and how, in iPhone you have the UITableView whose UI is ready, you only have to specify data source and application logic. It's that easy! This is done by using the UITableViewController. UITableViewController is a subclass of UIViewController and handles everything from the user interaction to the data source for our UITableView. It's view is always UITableView. Lets start our project and create one…


Create a plain subclass of UIViewController (without the XIB) and name it TasksViewController. Change the header file, for controller to extend UITableViewController:

@interface TasksViewController : UITableViewController

Now we have to display this controller and its view. We do this in the app delegate file. (ignore closed uiapplicationdelegate tag)

#import "TasksViewController.h"

@interface AppDelegate : UIResponder 
{
    TasksViewController *tasksViewController;
}

and use it in the applicationdidFinishLaunchingWithOptions method of the implementation(.m) file:

tasksViewController = [[TasksViewController alloc] init];
    
[self.window setRootViewController:tasksViewController];
[self.window makeKeyAndVisible];

Now when you run the app, you should get something like this


We'll that's impressive. We have a fully functional … blank table.
We have to have things to fill our table so we will have to write a model to be used as a datasource for our table. I will create a class Task with basic attributes like number, description, dateCreated, highPriority and finished.
You can ignore following lines of code since goal of this tutorial is to learn UITableView, not the models in Objective-C.

#import 

@interface Task : NSObject
{   
    NSString *taskId;
    NSString *description;
    NSDate *dateCreated;
    BOOL highPriority;
    BOOL finished;
}

- (id)initWithDescription:(NSString *)desc;

@property (nonatomic,retain)  NSString *description; 
@property (nonatomic,retain)  NSString *taskId;
@property (nonatomic,retain)  NSDate *dateCreated;
@property (nonatomic) BOOL highPriority;
@property (nonatomic) BOOL finished;

@end


#import "Task.h"

@implementation Task

@synthesize taskId, description, dateCreated, highPriority, finished;

-(id) initWithDescription:(NSString *)desc
{
    self = [super init];
    
    if (self) {
        self.taskId = [NSString stringWithFormat:@"%c%c%c%c%c",
                       '0' + rand() % 10,
                       'A' + rand() % 26,
                       '0' + rand() % 10,
                       'A' + rand() % 26,
                       '0' + rand() % 10];
        
        self.description = desc;
        self.dateCreated = [[NSDate alloc] init];
        self.highPriority = FALSE;
        self.finished = FALSE;
    }
    return self;
}

-(void) dealloc
{
    [taskId release];
    [description release];
    [dateCreated release];
}
@end

Now we will create list of tasks and place them in grouped table view. For view to know what to display, our controller will have to implement UITableViewDataSource protocol which requires
two methods: tableView:numberOfRowsInSection: and tableView:cellForRowAtIndexPath:
These methods tell the table view how many rows it should display and what to display in each row.
In second method we will implement standard pattern used by lists in UITableViews - reusing cells with specific identifier, in our case UITableViewCell. This prevents us from running out of memory.

UITableView is a container for UITableViewCells. A cell consists of a content view and an accessory view. Content view is where we display the content of our cell (wow?! :)) and has three subviews textLabel,detailTextLabel and imageView. Accessory is place where we keep additional buttons,checkboxes…

A UITableView asks its data source for the cells it should display
• when it's first added to the screen
• when reloadData is called
• when user scrolls
• when the table view is removed from the view hierarchy and then added back to the view hierarchy

Let's see the implementation...

#import 

@interface TasksViewController : UITableViewController
{
    NSMutableArray *tasks;
}

@end

#import "TasksViewController.h"
#import "Task.h"

@implementation TasksViewController

-(id) init
{
    self = [super initWithStyle:UITableViewStyleGrouped];
    
    if (self){
        tasks = [[NSMutableArray alloc] init];
        
        [tasks addObject:[[Task alloc] initWithDescription:@"First task"]];
        [tasks addObject:[[Task alloc] initWithDescription:@"Second task"]];
        [tasks addObject:[[Task alloc] initWithDescription:@"Third task"]];
        [tasks addObject:[[Task alloc] initWithDescription:@"Fourth task"]];
    }
    
    return self;
}

- (id)initWithStyle:(UITableViewStyle)style
{ 
    return [self init]; 
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     // number of rows 
    return [tasks count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    // initializing the cell with reuse option if cell already exists
    UITableViewCell *cell =
    [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                            reuseIdentifier:@"UITableViewCell"] autorelease];
    
    if(!cell){
        cell = [[[UITableViewCell alloc] 
                initWithStyle:UITableViewCellStyleDefault 
                 reuseIdentifier:@"UITableViewCell"] autorelease];
    }
        
    Task *task = [tasks objectAtIndex:[indexPath row]];    
    [[cell textLabel] setText:[task description]];
       
    return cell;
}
@end


Ok, thats great but in Wunderlist we have option to edit the position of our tasks and delete them. To make this look according to the iPhone style guide we shall also add a navigation bar where we will make this switch.
For this purpose we will use UINavigationController. We usually use it for navigation between screens, but it can also be effectively used as global toolbar.
This controller has two parts: UINavigationBar and controller displayed beneath. To start using UINavigationController we have to tell it from where to start, initialize a root controller. We shall have only one controller since we aren't switching screens.
We'll add new UINavigationController in the appDelegate application:didFinishLaunchingWithOptions:launchOption:

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:tasksViewController]; 
 [self.window setRootViewController:navigationController]; 

Now we'll be adding navigation buttons UINavigationItems in the UINavigationBar which is displayed on the top.
All UIViewController's have UINavigationItem as their integral part. They are used when controller is displayed by the UINavigationController but we still have to specify how. UINavigationBar has three default parts leftBarButtonItem, rightBarButtonItem and titleView. Here's how we set the buttons in the init method of TasksViewController

// Setting already available edit button
    [[self navigationItem] setLeftBarButtonItem: [self editButtonItem]];  
    // Set the title
    [[self navigationItem] setTitle:@"Tasks"];

Now when we have all the buttons let's implement the functionality for them...
We have to implement the way data is deleted and animated afterwards. We'll have to implement tableView:commitEditingStyle:forRowAtIndexPath: which receives two arguments, UITableViewCellEditingStyle in this case UITableViewCellEditingStyleDelete and NSIndexPath of the deleted row.

-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Are we deleting row?
    if (editingStyle == UITableViewCellEditingStyleDelete){
        
        // Remove object from tasks
        [tasks removeObjectAtIndex:[indexPath row]];
        
        // Remove object from tableView
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
                         withRowAnimation:UITableViewRowAnimationFade];
        
    }
}

Run the app and you will see the toolbar with our edit button. Press it and … it works?! How?
Thats one of the treats in iOS programming we don't have in other environments. You noticed in the previous steps that we added editButtonItem without instantiating it, importing it or without using any other action. That's because every controller has editButtonItem property automatically linked to default setEditing:animated: which sets our table in editing mode. When we press the button for the second time ,it calls our commitEditingStyle:forRowAtIndexPath: and saves current status of the UITableView. Thats why our app works without adding any extra code. Cool...

One more thing to do is to implement tableView:moveRowAtIndexPath:toIndexPath: which will enable us to reposition our rows

-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{   
    // Get the object we are going to move
    Task *task = [tasks  objectAtIndex:[destinationIndexPath row]];
    
    // We will delete and move it to another location so well have to retain it
    [task retain];
    
    // Remove it an move it to other place
    [tasks removeObjectAtIndex:[sourceIndexPath row]];
    [tasks insertObject:task atIndex:[destinationIndexPath row]];
    
    // We no longer need it 
    [task release];
}


Now we have everything what we need for editing (moving, deleting) our table. Run the app and test our cool new additions.

Now let's insert rows. We'll do this as they do in the Wunderlist, by entering text in the text bar above the list box. Lets first add the text field in the header view of the UITableView. First we have to implement tableView:viewForHeaderInSection: and tableView:heightForHeaderInSection: for TableView to know what to display and UITextFieldDelegate to receive actions from the text field.

@interface TasksViewController : UITableViewController 
{
    UIView *headerView;
    NSMutableArray *tasks;
}

-(UIView *) headerView;
@end

- (UIView *)tableView:(UITableView *)tv viewForHeaderInSection:(NSInteger) sec
{ 
    return [self headerView]; 
}

- (CGFloat)tableView:(UITableView *)tv heightForHeaderInSection:(NSInteger)sec
{
    return [[self headerView] frame].size.height;
}

And finally implementation of the haderView with cool see through texbox...

-(UIView *)headerView
{
    if (headerView) {
        return headerView;
    }   
    
    // Container for our textField
    float w = UIScreen.mainScreen.bounds.size.width;   
    
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(8.0, 8.0, w - 16.0, 30.0)];
    textField.placeholder = @"Add a new task";
    textField.borderStyle = UITextBorderStyleLine;
    UIColor *color = [[UIColor alloc] initWithRed:0.0 green:0.0 blue:0.0 alpha:0.3];
    textField.backgroundColor = color;
    [color release];
    textField.borderStyle = UITextBorderStyleRoundedRect;
    textField.font =  [UIFont systemFontOfSize:14];    
    textField.textColor = [UIColor whiteColor];
    [textField setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];  
    textField.delegate = self;
    
    headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0, w, 48)];  
    [headerView addSubview:textField];
    [textField release];
    
    return headerView;
}

We have to enable user to use the text box automatically so when he/she presses return, data is automatically added into the table.
For this will be using textFieldShouldReturn: method which will put current text from the UITextField into table when we press enter.

- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    [textField resignFirstResponder];
    
    if ([textField.text length] > 0) {
        [tasks addObject:[[Task alloc] initWithDescription:textField.text]];
        [self.tableView reloadData];
        [textField setText:@""];
    }
   
    return YES;
}

It's seems we're making progress, but it doesn't look as "rich" as it should be. We'll add special cells which will enable us to click finished tasks and mark them as high priority. With current (default) implementation we can use textLabel, detailTextLabel and imageView which aren't enough. We'll have to subclass the UITableViewCell and make custom cell for our special purposes.

Create a new subclass of UITableViewCell from the menu. I will name it TaskCell. We'll add a UILabel for description easily but iPhone doesn't have a checkbox for our priority/finished values so we'll have to create one on our own.. We'll use UIButton for this purpose and set the background image which will make them look like checkboxes. We come to the part in which I suck and that is drawing so I will have to improvise... :(

@interface TaskCell : UITableViewCell
{
    UILabel *descriptionLabel;
    UIButton *finishedCheckBox;
    UIButton *highPriorityCheckBox;
}

-(void)setTask:(Task *)task;


And for implementation we'll define two methods, first is the standard initWithStyle:reuseIdentifier where we will initialize all the cell components.

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Standard label initalization
        descriptionLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        descriptionLabel.backgroundColor = [UIColor clearColor];
        [self.contentView addSubview:descriptionLabel];
        [descriptionLabel release];
        
        // Define images for all three states
        finishedCheckBox = [[UIButton alloc] initWithFrame:CGRectZero];
        [finishedCheckBox setBackgroundImage:[UIImage imageNamed:@"checkbox.png"] 
                                    forState:UIControlStateNormal];
        [finishedCheckBox setBackgroundImage:[UIImage imageNamed:@"checkbox-pressed.png"] 
                                    forState:UIControlStateHighlighted];
        [finishedCheckBox setBackgroundImage:[UIImage imageNamed:@"checkbox-checked.png"] 
                                    forState:UIControlStateSelected];
        [finishedCheckBox setCenter:CGPointMake(100,200)];
        [finishedCheckBox addTarget:self action:@selector(toggleCheckBox:) 
                   forControlEvents: UIControlEventTouchUpInside];
        [self.contentView addSubview:finishedCheckBox];
        [finishedCheckBox release];
        
        highPriorityCheckBox = [[UIButton alloc] initWithFrame:CGRectZero];
        [highPriorityCheckBox setBackgroundImage:[UIImage imageNamed:@"star.png"] 
                                    forState:UIControlStateNormal];
        [highPriorityCheckBox setBackgroundImage:[UIImage imageNamed:@"star.png"] 
                                    forState:UIControlStateHighlighted];
        [highPriorityCheckBox setBackgroundImage:[UIImage imageNamed:@"star-checked.png"] 
                                    forState:UIControlStateSelected];
        [highPriorityCheckBox setCenter:CGPointMake(100,200)];
        [highPriorityCheckBox addTarget:self action:@selector(toggleCheckBox:) 
                   forControlEvents: UIControlEventTouchUpInside];
        [self.contentView addSubview:highPriorityCheckBox];
        [highPriorityCheckBox release];
        
    }
    return self;
}

Second method is layoutSubwiews. You probably noticed that we didn't' specify size of the used elements. That's because we don't know them at this point. Just before the cell is loaded message is sent to layoutSubwiews and at this time dimensions are available. We'll define three containers for each element spreading them equally on the cell.

- (void) layoutSubviews
{
    [super layoutSubviews];
    
    // Checkbox and texbox dimensions and positions
    CGRect bounds = [[self contentView] bounds]; 
    float h = bounds.size.height;
    float w = bounds.size.width;
    float c = 15.0;
    float x = (h-c)/2;
    float valueWidth = 40.0;
    float space = 10.0;
    
    CGRect contentFrame = CGRectMake(x, x, c, c);
    [finishedCheckBox setFrame:contentFrame];
    
    contentFrame.origin.x += contentFrame.size.width + space; 
    [highPriorityCheckBox setFrame:contentFrame];
    
    contentFrame.origin.x += contentFrame.size.width + space; 
    contentFrame.size.width = w - ((h-c)/2 + valueWidth + space * 4); 
    [descriptionLabel setFrame:contentFrame];
    
}


Run the app and see what happens. We started from scratch and now we have a fully functional good looking UITableView with few neat tricks.
Unfortunately I haven't got more time, but when I find some I will try to add more functions to the UITableView, add SQLite storage and connect it to apropriate API by using ASIHttp and JSON framework. Hope I helped someone with this....