Frame debugging on a device

:  ~ 1 min read

There's this handy feature, Debug -> View Debugging -> Show View Frames, which, if turned on, draws borders around views. The sad part is that it only works on the simulator. But we can (somewhat) easily simulate its behavior.

First, we create a helper method that does the coloring:

func activateFramesDebug() {
  guard debugFrames else { return }

  layer.borderWidth = 1
  layer.borderColor = UIColor(
    hue: CGFloat(arc4random_uniform(100_000)) / 100_000,
    saturation: CGFloat(arc4random_uniform(100_000)) / 100_000,
    brightness: 0.5 + CGFloat(arc4random_uniform(50)) / 100,
    alpha: 1.0).CGColor
}

Then, we override drawRect / layoutSubviews, depending on the extension:

// Easy to avoid production slips, easy way to turn on / off.
#if DEBUG && false
let debugFrames = true
extension UILabel { // UIImageView, etc...

  override public func layoutSubviews() {
    super.layoutSubviews()
    activateFramesDebug()
    
}

extension UIButton { // UITableViewCell, UICollectionViewCell, etc...

  override public func draw(_ rect: CGRect) {
    super.draw(rect)
    activateFramesDebug()
  }
  
}
#else
let debugFrames = false
#endif

It will not always work perfectly, it's not a perfect solution, but it's better than nothing. I'm also hoping there's an easier / better way to do this, but I don't know where we could hook up in an UIView extension. Let me know @rolandleth if you find a better solution.