Archive for the ‘Objective-C’ Category

UITextField: how to dismiss the Number Pad keyboard

July 11, 2010

By default the Number Pad keyboard unlike the default keyboard does not have a “Done” button. I tried a number of different techniques to dismiss the keyboard, e.g., set the UITextField’s delegate to the ViewController and then add this method:

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [textField resignFirstResponder];
}

But this didn’t work. The method would get called, but the focus still remained in the UITextField. Instead, I chose to use the touches methods to dismiss the keyboard. This allows the user to touch anywhere outside of the text field to dismiss the keyboard. Here is a method that will dismiss the keyboard:

-(void)touchesBegan: (NSSet *)touches withEvent:(UIEvent *)event
{
       // do the following for all textfields in your current view
	[self.my_text_field_1 resignFirstResponder];
       // save the value of the textfield, ...
}

Sharing SQLITE connection on iPhone threads may leave you hanging

June 17, 2010

iPhone SDK makes asynchronous operations really easy to use. There is no excuse for not making an application where the UI freezes whilst you’re downloading a URL or running a time-consuming SQL query. Here is an example of creating a background task (using NSInvocationOperation class) that you could call once the UI view has been initialized. In this example, the method init_data_details will be assigned its own thread and it will run in the background leaving the main thread for accepting user input. You’ll need to create a queue which here I’ve done in the Application Delegate class (essentially as a global variable that can be accessed from all views).

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSInvocationOperation *operation = 
    [[NSInvocationOperation alloc] 
        initWithTarget:self 
        selector:@selector(init_data_details) 
        object:nil];
[appDelegate.queue addOperation:operation];
[operation release];

In the init_data_details, I was running SQL queries on a local SQLITE3 database. To improve the performance of SQLITE, I was reusing a connection and all prepared statements. In case of memory warnings, I closed the connection and sqlite3_finalize all prepared statements. The problem was that I was sharing the same connection across multiple threads. This resulted in mysterious crashes with SQLITE3 stack traces that always ended up at sqlite3VdbeMemGrow. The fix in this case was to open a new connection (and prepare new statements) for all SQL accesses that were taking place in the background thread. Here is the outline of the operation:

- (void) init_data_details
{
// SQL is my encapsulation of the access to SQLITE3
// It creates a connection, handles open/close and 
// prepare statements

	SQL *sql2 = [[SQL alloc] init];
	
// pass this new connection to methods that need to access 
// the database in the background thread.

	NSMutableArray *data_array =
        [Someclass/object method  connection:sql2];

// process the data, update the UI, ...
// Here updating a UITableView object called
// overview_table

	[overview_table reloadData];

// Close connection, finialize prepare statements 
// for this connection, ...
	[sql2 close_connection];
	[sql2 release];
}

UIColor using RGB macro

May 30, 2010

The default OS X color picker does not show you the RGB color code. There are a number of other color pickers that you can install and they will extend the standard color picker giving you access to this information. I use the Rubicode’s RCWebColorPicker.

Once you’ve access to the RGB values you can use a C macro to define a shortcut for passing this RGB and getting a UIColor. Here I’ve defined two macros: RGB and AC_BLUE. The first takes three arguments and will yield a UIColor object. The AC_BLUE is an example of how you could use this macro to set the color palatte for your objective-C application.

You can define these macros in your project’s MyProject_Prefix.pch file so that they are available to all of the classes in your application.

#define RGB(r, g, b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
#define AC_BLUE RGB(0x00, 0x95, 0xD2)

Adding your own colors to core-plot

March 29, 2010

In HTML colors are typically specified in a HEX format, where each color is a number from 0 to 255 represented as a two digit hex number. For example, the aqua blue shade color is represented as 0095D2, where the value for Red is 00, the value for Green is 95 and the value of Blue is D2. For iPhone development, the colors are specified in RGB float where each of the RGB colors is a number between 0.0 to 1.0.

In core-plot, you can add your own colors via Objective-C category construct from within any of your own header and implementation files.

@interface CPColor (AQ_COLOR)
 +(CPColor *)aq_blue_color; // #0095D2 
@end
@implementation CPColor (AQ_COLOR)

+(CPColor *) aq_blue_color { 
    static CPColor *color = nil;
    if ( nil == color ) {
		color = [[CPColor alloc] initWithComponentRed:(0x00&0xff)/255.0 green:(0x95&0xFF)/255.0 blue:(0xD2&0xFF)/255.0 alpha:1.0];
    }
	return color; 
}
@end

Now you can use this color to fill a bar chart, e.g.

barPlot.fill = [CPFill fillWithColor:[CPColor aq_blue_color]];

UIPickerView sample

May 20, 2009

UI to select a state from the picker to update the image/label. The arrow button controls the visibility of the picker.

UI to select a state from the picker to update the image/label. The arrow button controls the visibility of the picker.

There is no built-in drop down list in iPhone SDK. You’ll need to create the interaction from the combination of the Picker and some other control, e.g., a button. Here are the steps to create and initialize a UIPickerView for all the 50 States:

Start Interface Builder and drag a Picker View object from the Library tool to the View object. This will create a UIPickerView object for you. Alternatively you can programmatically create this object in Xcode. But it is easier to use the IB. If you now build and run your project, you wont see the picker. To see it you’ll need to set the data source and delegate.

In IB, control-click on the Picker and then drag and connect the dataSource and delegate outlets to the File’s Owner for the view controller. Now if you build and run your application, you’ll see an empty picker. The control-click on the picker is a short cut for connecting the data source and the delegate properties. In addition, you’ll need to connect the picker to your view controller to create the object so that you can access it in Xcode. You do this by dragging the New Referencing Outlet from the IB’s Picker VIew Connection to the File’s Owner object in the xib file view. Alternatively, when you control-click, you can drag a New Referencing Outlet from the popup.
(more…)

Adding button and its handler in Objective-C using iPhone SDK

May 17, 2009

In JavaScript, it is fairly easy to add a button and its event handlers. HTML and the browser are your Interface Builder and your text editor is your Xcode. There is no need to graphically connect anything and there is no confusion where you add the button and where you add the event handlers. For iPhone programming, the model is more sophisticated and hence it is more complicated to nail the basics. So how do you add a simple button and its event handler in Objective-C and iPhone SDK?

Typically you will want to add a button using the Interface Builder and then add the button’s event handlers in Xcode. Here are the steps:

  1. In Xcode double click on the NIB file that defines the view to which you wish to add a button. This will start the Interface Builder (IB).
  2. In IB, open the Library tool and drag a button to the view. Position and resize this button and give it a title.
  3. Now you need to connect the button to the View Controller class so that you can control and customize this button from Xcode. You can control-click on the button and drag the connection line to the File’s Owner in the xib view (alternatively, you can start the IB’s Inspector, select the Button Connection tab and create a Referencing Outlet – drag the connection similar to before).
  4. In Xcode you’ll need to define the button to the view controller’s interface file and then define the methods to customize the button and define its events handlers.

In this sample, I’ve added a UILabel and a UIButton class so that when you click on the button the value of the label is changed.

@interface TestViewController : UIViewController {
	IBOutlet UILabel *mylabel;
	IBOutlet UIButton *mybutton;
}
@property (nonatomic, retain) UILabel *mylabel;
@property (nonatomic, retain) UIButton *mybutton;
@end

In the implementation file, you need “synthesize” the label and button objects.

@implementation TestViewController

@synthesize mylabel;
@synthesize mybutton;

Next I try to customize the label on the button and add an event handler.

- (void)viewDidLoad {
        [super viewDidLoad];
	mylabel.text = @"www.aquacue.com";
	[mybutton setTitle:@"Aquacue - Normal" forState: (UIControlState)UIControlStateNormal];
	[mybutton setTitle:@"Aquacue - Highlighted" forState: (UIControlState)UIControlStateHighlighted];
	[mybutton addTarget:self action:@selector(myButtonClick:) forControlEvents:(UIControlEvents)UIControlEventTouchDown];
}

Now here is the definition of the handler:

-  (void)myButtonClick:(id)sender {
	mylabel.text = @"Clicked";
}

Next I add another event handler so that when you click on the screen background, the value of the label is changed:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    mylabel.text = [NSString stringWithFormat: @"Hello Aquacue %@ %d", @"AAA", event.timestamp];
    [super touchesBegan:touches withEvent:event];
}

You can also use the IB to define event handlers (aka Actions). The easiest way is to actually define the handler/action in Xcode using the IBAction declaration in the interface file (add the declaration just before the @end statement).

- (IBAction)myButtonPressed:(id)sender;

Next you’ll need to define the myButtonPressed handler in the implementation file:

- (IBAction)myButtonPressed:(id)sender {
	mylabel.text = @"Change the label, when user clicks on the button";
}

Note that in this sample, I’ve defined two handlers one using the UIButton addTarget method and another using the IBAction. Both of these handlers are called when the user clicks on the button. As it turns it both of these handlers get called IBAction gets called first followed by the handler that was added via addTarget.

Only the methods defined with the IBAction declaration are exposed to the IB. You can control-click on the button object in IB and you’ll see a popup menu that defines all of the events that the object is willing to handle. Using the normal IB way, you’ll need to drag an event to the File’s Owner object to expose the event handler in Xcode.

Objective-C & string concatenation

May 17, 2009

I’ve started learning objective-C for my iPhone SDK programming project and was wondering how to concatenate strings and integers, … I saw a number of posts on the web about how verbose Objective-C is compared to C#. No mention was made that C# arrived 20 years after  Objective-C and it was a poorer version of Java. Anyhow, want to concatenate a bunch of primitive types as a string? Here is what you do (recall your sprintf syntax)

[NSString stringWithFormat: @"Hello Aqua %@ %d", @"cue ", 1];

For string concatenation, Objective-C is almost as concise as Perl -)


Follow

Get every new post delivered to your Inbox.