Showing posts with label objective-c. Show all posts
Showing posts with label objective-c. Show all posts

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.




Wednesday, 25 July 2012

The correct way to use your own NSError objects in your app

Thanks to Mike Abdullah @mikeabdullah for pointing out the 'deliberate' (ahem) mistake in this post the first time around. Oops.

Saturday, 21 April 2012

AppCode Delegate Pattern Live Template

Here's a Live Template to generate a common delegate pattern in AppCode, JetBrain's Objective-C IDE.

Tuesday, 14 September 2010

iPhone SDK: Running a selector after a delay..

Quite often I've needed to run a selector after a certain time interval. Usually what I've done is the following:

[NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(doIt:) userInfo:nil repeats:YES];


A shorter and slightly easier method is a selector on NSObject (now that's a base class with a lot of methods if ever I've seen one!)

[self performSelector:@selector(doit) withObject:nil afterDelay:1.0];


If you set afterDelay to be 0.0, you have a quick and easy way of making a selector run once the current run loop has completed.

Thursday, 9 September 2010

iPhone SDK: What NSURL methods actually return

Apple's NSURL documentation has very little detail on what exactly the various NSURL methods actually return. It just says unhelpful things like 'returns the path' - what path?

Here's an example NSURL, and the output you actually get when using some of the methods.

NSURL* url = [NSURL URLWithString:@"http://username:password@www.example.com:888/folder1/folder2/filename.html?query1=value&query2=value#anchor1"];
[url scheme] -> "http"
[url user] -> "username"
[url password] -> "password"
[url host] -> "www.example.com"
[url port] -> "888"
[url path] -> "/folder1/folder2/filename.html"
[url lastPathComponent] -> "filename.html"
[url pathExtension] -> "html"
[url fragment] -> "anchor1"
[url absoluteString] -> "http://username:password@www.example.com:888/folder1/folder2/filename.html?query1=value&query2=value#anchor1"

Wednesday, 25 August 2010

Pop up a list of options - iPhone SDK

Here's a quick snippet for popping up a list of options using the UIActionSheet in iPhone OS.

What's slightly confusing is that the index of the 'cancelButton' is 1, and 'destructiveButton' is 0, even though 'cancelButton' is listed first in the initWithTitle selector. This gets me each time!


// place this code in a UIViewController subclass

- (void)debugButtonPressed:(id)sender
{
UIActionSheet* action = [[UIActionSheet alloc]
initWithTitle:@"Menu"
delegate:self
cancelButtonTitle:@"Continue"
destructiveButtonTitle:@"Quit"
otherButtonTitles:@"Debug",nil ];
[action showInView:self.view];
[action release];
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0: // Quit
NSLog(@"Quit");
break;
case 1: // Continue
NSLog(@"Continue");
break;
case 2: // Debug
NSLog(@"Debug");
break;
}
}