Can I adjust a CGRect with a UIEdgeInsets?

TL;DR

Swift 4.2 use theRect.inset(by: theInsets).

Objective c use UIEdgeInsetsInsetRect(theRect, theInsets)

Example

// CGRectMake takes: left, bottom, width, height.
const CGRect originalRect = CGRectMake(0, 0, 100, 50);

// UIEdgeInsetsMake takes: top, left, bottom, right.
const UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, -20, -20);

// Apply the insets…
const CGRect adjustedRect = UIEdgeInsetsInsetRect(originalRect, insets);

// What's the result?
NSLog(@"%@ inset by %@ is %@", 
      NSStringFromCGRect(originalRect),
      NSStringFromUIEdgeInsets(insets),
      NSStringFromCGRect(adjustedRect));

// Logs out…
// {{0, 0}, {100, 50}} inset by {10, 10, -20, -20} is {{10, 10}, {110, 60}}

Explanation

  • A positive inset moves the rectangle's edge inwards (towards the rectangle middle).
  • A negative inset moves the edge outward (away from the rectangle middle).
  • A zero inset will leaves the edge alone.

Tell Me More

Further useful functions for operating on CGRects are covered by this note.


2018 ... Swift4

Say you want the bounds,

but for example less two pixels on the bottom:

let ei = UIEdgeInsetsMake(0, 0, 2, 0)   // top-left-bottom-right
let smaller = UIEdgeInsetsInsetRect(bounds, ei)

That's it.

If you prefer to write it as one line, it's just

Take two off the bottom:

let newBounds = UIEdgeInsetsInsetRect(bounds, UIEdgeInsetsMake(0, 0, 2, 0))

Cheers


Still 2018 ... Swift 4.2

I guess the new way looks better...

let newCGRect = oldCGRect.inset(by: UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8))