Ignore touches to UIView subclass, but not to its subviews

Note: I’ve moved all future technical/programming posts out of this blog and over to objectivesea.tumblr.com. Follow that one if you’re going to follow me for technical junk.

If you want a UIView subclass to ignore touch events, just set its userInteractionEnabled property to NO. But that will block touches to all its subviews. To ignore touches in a UIView subclass, but not its subviews, just work a little hitTest magic:

-(id)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    id hitView = [super hitTest:point withEvent:event];
    if (hitView == self) return nil;
    else return hitView;
}

How to set default values for NSUserDefaults

NSUserDefaults is a great place to store your apps settings. It is convenient, available everywhere, and integrates nicely with settings bundles. One problem you run across with NSUserDefaults, is setting default values for your settings. There is a very simple elegant solution to this, detailed below.

Define keys

Use defines to keep keys consistent I usually have one header file just for keys I use throughout the project.

Create a defaults property list

Set default values in a new property list Create a new property list, and enter default values for all your settings. Make sure the keys match the ones you #define-d. Also pay attention to the types.

Set defaults on launch

The following code needs to run every time your app launches (in case your NSUserDefaults have gotten nuked or mangled). I added the following three lines to application:didFinishLaunchingWithOptions: in my app delegate.

NSString *defPath = [[NSBundle mainBundle] pathForResource:@"DEF" ofType:@"plist"];

NSDictionary *defaultsDict = [NSDictionary dictionaryWithContentsOfFile:defPath];

[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsDict];

Fantastic, you are done.

DMURLConnection

A very very light wrapper for NSURLConnection. I wrote it, found it useful, thought that I would share. For when you need to send an HTTP post request and download some kind of response asynchronously.

NSDateFormatter format strings for Twitter and Facebook

Format strings for processing dates from facebook or twitter’s json api’s

//2010-09-12T22:21:18+0000
#define DF_FACEBOOK @"yyyy-MM-dd'T'HH:mm:ssZZ"
// Sun Sep 12 17:06:56 +0000 2010
#define DF_TWITTER @"EEE LLL dd HH:mm:ss ZZ yyyy"

Usage:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setTimeStyle:NSDateFormatterFullStyle]; // important
[df setDateFormat:DF_TWITTER];
NSDate *date = [df dateFromString:dateStringTwitter];
[df release];

Where DF_TWITTER would be DF_FACEBOOK, if you were processing facebook json instead of Twitter.

How to vertically center a UITextView

Note: I’ve moved all future technical/programming posts out of this blog and over to objectivesea.tumblr.com. Follow that one if you’re going to follow me for technical junk.

This took me ages to figure out how to vertically center the text in a UITextView. There really ought to be a property to set, but there isn’t so… this is pretty easy.

In -(void)viewDidLoad, add this to observe the contentSize key value:

[textView addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];

Then add this method, which adjusts the contentOffset every time the contentSize value changes.

-(void)observeValueForKeyPath:(NSString *)keyPath   ofObject:(id)object   change:(NSDictionary *)change   context:(void *)context {
 UITextView *tv = object;
 CGFloat topCorrect = ([tv bounds].size.height - [tv contentSize].height * [tv zoomScale])  / 2.0;
 topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
 tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
}

Et voila!

Anti-If Campaign

I’m trying, I’m trying!!!

The basic problem is that IFs create dependencies, coupling between modules (methods, objects, components, etc.) and increases possible paths inside our code (which reduces legibility)

FileMaker Custom Function: Hex to Decimal

This FileMaker Pro Custom Function converts a single character from hex to decimal.

I’m using it to convert an HTML-style hex colour into decimal, and then floating point values. I grab two characters from the string, pass each one to the function, and then divide the result by 30. The first two characters represent red, second two green, last two are the blue.


Function name: HexToDec

Function parameters: hexCharacter

Let (a = Upper ( Left(hexCharacter; 1) ); 
Case (
a = "0"; 0;
a = "1"; 1;
a = "2"; 2;
a = "3"; 3;
a = "4"; 4;
a = "5"; 5;
a = "6"; 6;
a = "7"; 7;
a = "8"; 8;
a = "9"; 9;
a = "A"; 10;
a = "B"; 11;
a = "C"; 12;
a = "D"; 13;
a = "E"; 14;
a = "F"; 15;0)
)

Hot Cocoa - iPhone and Mac code blogs

Google Reader lets you create bundles, collections of blog feeds, for to share with the world. This is my collection of coding blogs. I read other blogs that touch on the subject occasionally, but these are the almost-only-programming blogs. Right now that means:

All-Seeing Interactive Blog

Cocoa Blogs

Cocoa Is My Girlfriend

Cocoa Samurai

Cocoa with Love

Dave Dribin’s Blog

iPhone Development Blog

iPhoneDevelopmentBits

M Cubed Blog

NSBlog

Ray Wenderlich

Square Signals