Thanks to Mattt Thompson’s great NSHipster blog, a lot of folks are now “hip” to some pretty obscure stuff in Cocoa and Objective-C. It’s a great blog. Go read it.

It’s not always completely obvious how to use the new tools he highlights though. I found myself reading his article on CGGeometry, utterly surprised by the existence of all those useful convenience functions. But if you’re already sticking numbers into CGRectMake (as I have been doing for forever), then why would you need functions like CGRectOffset, CGRectInset, and CGRectDivide ?

Simple. Don’t use  CGRectMake. Instead, keep track of a working rectangle.

For example, let’s say you’re trying to lay out a tableview cell.

- (void) layoutSubviews {
    [super layoutSubviews];

    CGRect workingRect = self.contentView.bounds;

This workingRect variable is your home base. It represents the part of your view that hasn’t been sliced up yet. Let’s say you want to pad everything by a few pixels.

workingRect = CGRectInset(workingRect, 2, 2);  

Bam. Done. You want to lay out your imageView, textLabel, and detailTextLabel, so set up some variables.

CGRect imageRect = CGRectZero, textRect = CGRectZero, detailTextRect = CGRectZero;  

Okay, time to use the coolest of the tools.  CGRectDivide takes a rect, an amount, and an edge, and “returns” a slice and a remainder.

CGRectDivide (CGRect rect, CGRect *slice, CGRect *remainder, CGFloat amount, CGRectEdge edge);  

Let’s assume you’re lazily loading your subviews, so check if you’ve got an image and divide your  workingRect  up. The crucial thing here is to pass your workingRect for your remainder, so that you can keep working with it. Cut off a square from the left side with a square for the imageView.

if (_imageView.image) {  
	CGRectDivide(workingRect, &imageRect, &workingRect, workingRect.size.height, CGRectMinXEdge);  

Boom. You have an imageRect now, and you can continue to work with your workingRect. Do the same with your  detailTextLabel.

if (_detailTextLabel.text.length) {  
	CGRectDivide(workingRect, &detailTextRect, &workingRect, workingRect.size.height/2, CGRectMaxYEdge);  

The leftover, whatever it is, is the textRect.

textRect = workingRect;  

Now you can just set your rects to the frames of your objects!

	self.imageView.frame = imageRect;  
	self.textLabel.frame = textRect;  
	self.detailTextLabel.frame = detailTextRect;  

You’re done. Easy like Sunday morning, and a lot more readable than a half dozen CGRectMake calls.