Wednesday 21 November 2012

BVUnderlineButton - iOS Control for web-link style button

My client requested a web-link style button for a forgot password button on the log-in screen, which seemed on the surface to be a simple thing to implement.

After looking into it I was surprised to learn that there's no built-in way to underline text in a UI element on iPhone - you have to simply draw it yourself.

Searching the web I found some sample code in varying states of usability. By sticking these together and putting a couple more features in I came up with CVUnderlineButton.

It's available on GitHub at https://github.com/benvium/BVUnderlineButton

Simple example button


Here's the README for the control.


BVUnderlineButton

Simple UIButton subclass that draws a button with the title underlined.
Based on code originally found at http://davidjhinson.wordpress.com/2009/11/26/underline-text-on-the-iphone/ with all the fixes from the comments and some further tweaks.
This code requires ARC.

Usage

Add BVUnderlineButton.m and BVUnderlineButton.h to your project.
If you're using a Storyboard or XIB files:
  • drag a UIButton to your stage, set the 'Type' (under Attributes Inspector / Button) to Custom
  • Set the Class (under Identity Inspector / Custom Class) to BVUnderlineButton.
If you're using code, just create the button as you would a regular Custom style UIButton, e.g.
#import "BVUnderlineButton.h"

BVUnderlineButton *button = [BVUnderlineButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self 
       action:@selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:@"underlined" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[view addSubview:button];
Adjusting the underline position

Depending on the font you may wish to adjust the vertical position of the underline using the underlinePosition property. The default is -2 pixels.
If you're using a Storyboard or XIB files:
  • Select the BVUnderlineButton instance on your stage.
  • Open the 'Identity Inspector' and click the + under 'User Defined Runtime Attributes'
  • Type 'underlinePosition' for keyPath, choose 'Number' for type, and type in the new value as a floating-point number (e.g. 1)
If you're using code, just set the underlinePosition property.
button.underlinePosition = 1;

Wednesday 14 November 2012

RestKit: Could not find an object mapping for keyPath: ' '

RestKit is an excellent Objective-C framework to make dealing with downloading and uploading data to and from a REST-based server considerably simpler than coding it all yourself.

When I started out I found it pretty straightforward until I hit a REST command that returned a JSON array at the root object, where I ran into the dreaded Could not find an object mapping for keyPath: ' ' error.

Here's an example REST response that caused this error:

[ { "name":"foo"}, { "name":"bar"} ]

It seems restkit expects there to be a root level object e.g. 

{ "data": [ { "name":"foo"}, { "name":"bar"} ] }

If your server doesn't do this, and you can't change it, then the automatic mapping system doesn't seem to work.

The solution is pretty simple (manually tell the system which mapping to use) but I took me a while to figure out, so I thought it might help others if I posted it here.