Tom Benner's NUI_blog

On a recent iOS project, we realized that we had a large number of screens with custom designs and Apple's Interface Builder wasn't going to cut it. A lot of styling components that one can access in views simply aren't exposed in Interface Builder. We were going to have a codebase dominated with subclasses of elements with names like AppThemedUITabBar, SubmissionTextField, and BottomBorderedUIView. While there isn't anything objectively wrong with this, it certainly feels like the wrong level of abstraction for what is essentially a design concern, and so we searched for a better solution. We found NUI.

What is NUI?

NUI is a drop-in UI kit for iOS that lets you style UI elements using a stylesheet, similar to CSS. Using it, you can attach a string "NUI class" to your UI elements, then the NUI library will apply your styling globally to all UI elements that contain that class. Your styling directives are all specified in a file with an .nss extension (typically something like app.nss or theme.nss). This helps separate styling from code, and in general keeps your code easier to change.

Sample theme.nss

# Sample theme.nss

@primaryFontName: ProximaNova-Regular;
@primaryFontSize: 17;

CaptionTextLabel {
    font-name: @primaryFontName;
    font-size: @primaryFontSize;
    font-color: #333333;
}

CaptionContainer {
    padding: -10 0 0 0;
}

SubmissionText {
    font-size: @primaryFontSize;
    line-height: 3.5;
}

The Good News

The NUI engine itself is reliable and fast.

The things we worried about, "Is this going to be slow to render? Will this feel non-native?" were complete non-issues.

Additionally, the variety of .nss directives available is extensive and exposes many styling options that aren't available in interface builder like:

  • UIView corner-radius
  • UINavigationBar background-image-insets
  • UITextField shadow opacity, radius, colors and offsets
  • UISwitch on/off images and tint colors
  • UILabel text alpha

Live update is a lovely feature for huge codebases as well. With it enabled, you don't need to rebuild between changes. Changes made to the .nss source file are updated live in the simulator.

The Bad News

The code for NUI contains a fair bit of duplication and missing functionality. A few NUI directives available for one UI element aren't available for another. UITextView and UITabBarItems, for some inexplicable reason, don't have any NUI support at all. Greg submitted pull requests to the author adding support for them, and hopefully by the time you read this they've been included.

When developing in NUI, you may also find yourself wanting to add multiple classes to the same widget. For example, you may want a header label that styles like a header, but has the border and padding of a hero box. As far as I know, it's not possible.

Another problem is that you can't do multiple stylesheets. For example, maybe you want to load ios6.nss on top of your main styles for iOS6-specific tweaks. We submitted a pull request adding an appendStylesheet option to NUI that adds that functionality.

One gotcha is out-of-control memory consumption when the live update feature is enabled. Perhaps it's obvious, but I spent a number of days tracking down memory crashes only to discover that the live update feature was holding onto a reference for each UI element rendered to screen.

It's also worth noting that it looks like CSS, it feels like CSS, but the cascading part of cascading style sheets is not present. You can't nest rules within each other, add media selectors, or create selectors for anything but NUI classes or global types. This is frustrating and leads to a lot of duplication.

Finally, typos are blatantly ignored by the parser, and developers can spend a fair amount of time wondering why text-color doesn't work only to discover it's because the property is called font-color.

The verdict

In spite of my obvious gripes, I found NUI to be a valuable addition to my Objective-C toolkit. The CSS-like concept of defining selectors and styling rules is immediately familiar for devs coming from webdev backgrounds, and in the future I'll use it again.

When Mike's not working or off making his own apps and games he can be found on Twitter.

Images from the NUI project page.