Xcode 5.0 introduced an interesting new feature: Quick Look for variables. Basically, it lets you inspect variables and their contents in a graphical way. This allows for interesting ways of viewing the state of your app.
I've been using the feature quite a bit: it's a great way to inspect images or colors you're using in your app, for example. Works great on attributed strings, too.
Xcode 5.1 improves the feature even further with the addition of debugQuickLookObject
. This method allows you to provide quick look content for any of your own classes. A bit like debugDescription
but more advanced. I haven't had the time to look further into it.
iOS Dev Weekly to the rescue
But now it's friday, and reading the latest edition of iOS Dev Weekly, I saw a link titled Quick Look on UIViews (the article itself is called Xcode Debugger Quick Look). My interest was immediately peaked: the quick look feature does not provide any specific support for UIViews, and it's been more than once where I had thought: "dammit it want to see what this view looks like". Because now you get this:
Not very useful. So my hopes were high for that article to provide a way to visualise views. And while it provided that, there was no general way to inspect any view. There were specific examples for labels etc, but nothing generic.
So I decided to implement this myself. Include "UIView+DebugQuickLook.m" into your project, and all your views automagically gain debugQuickLookObject
. Like this:
Internals
So how does this work? It's actually pretty simple:
- we define a category implementation on
UIView
(no interface needed since there's no public extensions for UIView). - implement the
+load
method in that category. This method is called when the class is loaded (the runtime will call load for the class and all its categories having theload
method). - In that load method, we invoke another class method that installs the
debugQuickLookObject
. - We check that
debugQuickLookObject
isn't already present onUIView
. This is in case Apple adds it themselves, or another library implements it for you: we don't want to break things in the future. - After that, we use
objc_addClassMethod
to add thedebugQuickLookObject
method toUIView
. We use ourimage_debugQuickLookObject
method as a template. This effectively adds a new method to all UIViews.
The whole @implementation
block is wrapped in an #if DEBUG ... #endif
block, since we only want to add this when debugging. There's no need to inject this code into your app when building for production use.
The image_debugQuickLookObject
(or debugQuickLookObject
once it's been added) method is pretty simple in itself:
- It creates an image context with the size of the view.
- It then tries render the view using
drawViewHierarchyInRect:afterScreenUpdates:
. - If that failed, it renders again using the view's layer.
- It then retrieves the image from the context
- and returns it. And that's it.
If you want to inspect the "full" code, check out the Github repo.
Get it on the internets
If you want to integrate this in your own projects, either can download the file from the Github repo (and add it manually to your project), or use CocoaPods. Just add:
pod 'UIView+DebugQuickLook', :git => 'https://github.com/Inferis/UIView-DebugQuickLook.git'
Enjoy!