Sunday, January 25, 2009

Dismissing the Virtual Keyboard on iPhone

This post is a quick recipe for making the virtual keyboard go away on the iPhone SDK. There are two aspects to the problem: dismissing the keyboard when the user taps Done (easy, most resources describe this right) and dismissing the keyboard when the user taps the screen outside any control that can receive focus.

When the user taps Done
Go to Interface Builder, and connect the edit control's delegate outlet to your view controller (in most cases, that will be the File's Owner). If your delegate is different, follow the steps below making changes when appropriate.

In the view controller, use the following snippet:

That's it, you're done. Run the code in the simulator and confirm it works.

When the user taps outside the field
You might see some more complicated solutions elsewhere (like Apress' book). The solution below works without any UI changes. Add the snippet below in your view controller. The snippet belongs in the view's controller, even if your text field's delegate is another object.

Bonus: reacting to the user leaving the field
If you want to take an action when the user leaves a field (such as issuing a Web service request in the background), the approach below plays nice with the modifications described in this post:

This code belongs in the text field's delegate (most of the time, it is your view controller).

I hope this post makes your life a bit easier. Happy coding!

Sunday, January 11, 2009

Date, time, and datetime validation in Rails 2.x

This is a very short post pointing to a good plug-in for validating time stuff in Rails. One-line summary: use validates_timeliness.

I wanted to validate the format of a datetime field in one of my models, so I tried validates_date_time and saw that Rails doesn't have it installed. I googled validates_date_time, and stumbled upon the plug-in with the same name by Jonathan Viney.

I installed the plugin, fixed the unit tests to run on Rails 2.2 with sqlite3, and then proceeded to write my validation, complete with unit tests. All the code is included, for your pleasure. After some booring debugging, I came to the conclusion the plugin can't handle invalid formats on new models, because of how it's using _before_type_cast to determine whether its parser failed or succeeded.

I googled for datetime validation in rails 2.2, hoping that someone fixed the bug. I didn't find a fix, but instead stumbled over the validates_timeliness plugin, written by Adam Meehan. In case you're seeing this in plain text, the link to the plug-in is

I hope Google indexes my post, and that it helps you avoid going through the same trouble that I have.

The code I used for this post:

Sunday, January 4, 2009

Auto-rotating Tab Bars on the iPhone

This post is a quick summary of what's needed to get a tab bar (like the one in the Clock application) to switch from portrait to landscape when the user rotates their phone. Accelerometer goodness, yum!

The process is easy, but it has a couple of pitfalls. Here are the steps:
  1. You have to override shouldAutorotateToInterfaceOrientation: in the view controllers for all the views in the tab bar. If a view controller's shouldAutorotateToInterfaceOrientation: returns NO, then the tab bar will not rotate, even if the view is hidden at the time of the rotation.
  2. You should not override the tab bar controller's version of shouldAutorotateToInterfaceOrientation:
  3. For regular views in the tab bar add the code below to viewDidLoad. If you skip this, your view will not resize when the phone is rotated while it's selected. However, it will resize when the user transitions to it from another view.

  4. Make sure the controls on your regular views respond to changes in view size. If you're using Interface Builder's springs and struts, you can test the views right in IB, using the arrow at the right of the views' title bars.
Acknowledgements: I used the knowledge in some forum posts that Google revealed to me, together with some testing.

I hope you found this useful. If you have more tips, please post them in the comments, and I'll edit the posting accordingly, so others can have an easier time finding this information.