hasseg.org

Use Unicode Emoji as Icons in Native iOS Apps

Filed under Featured, iOS, Programming

A while back, I wrote about using unicode emoji characters as icons in web apps. The big caveat with that was that these characters were only available on iOS devices, which made the trick much less useful in a web app, which of course are generally meant to be more or less cross-platform. If you're developing a native iOS app, though, using these standard colorful bitmap emoji characters as icons is a much more realistic proposition, because you can be sure that all the devices your app runs on will have them available. In this post I will show how to easily do this.

The easiest way to display emoji icons in your app's UI is to simply use a control that renders text, like a UILabel or a UIButton. Sometimes, though, you will want to render one of these characters into a UIImage so that you can manipulate the pixels somehow or simply to be able to show them in certain positions in certain controls that expect an image object.

In Speed Dialer Factory, I used emoji icons to make some options in table view cells a bit more recognizable:

In this particular case, I needed the emoji characters to be rendered into UIImages so that I could make them monochrome when the cells were disabled. In addition, using the image section of the table view cells allowed me to ensure that the labels of all of the cells were horizontally aligned.

Below you can find the source code for a UIImage category that I use for this. Here is an example how how I might use a method in this category to apply one of the above images into a table view cell:

tableViewCell.imageView.image = [UIImage hg_imageFromString:@"\uE001"];

And here is the source code:

UIImage+HGViewRendering.h:

#import <UIKit/UIKit.h>

@interface UIImage (HGViewRendering)

+ (UIImage *) hg_imageFromView:(UIView *)view;
+ (UIImage *) hg_imageFromString:(NSString *)str;
+ (UIImage *) hg_cachedImageFromString:(NSString *)str;

@end

UIImage+HGViewRendering.m:

#import "UIImage+HGViewRendering.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIImage(HGViewRendering)

+ (UIImage *) hg_imageFromView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

+ (UIImage *) hg_imageFromString:(NSString *)str
{
    UILabel *label = [[[UILabel alloc] init] autorelease];
    label.text = str;
    label.opaque = NO;
    label.backgroundColor = UIColor.clearColor;
    CGSize measuredSize = [str sizeWithFont:label.font];
    label.frame = CGRectMake(0, 0, measuredSize.width, measuredSize.height);
    return [UIImage hg_imageFromView:label];
}

+ (UIImage *) hg_cachedImageFromString:(NSString *)str
{
    static NSMutableDictionary *cache = nil;
    if (cache == nil)
        cache = [[NSMutableDictionary dictionary] retain];
    UIImage *image = [cache objectForKey:str];
    if (image != nil)
        return image;
    image = [UIImage hg_imageFromString:str];
    [cache setObject:image forKey:str];
    return image;
}

@end

1 Comments

Paul May 4, 2012 at 7:38 PM

I’m currently test driving this in an app I’m developing and so far it looks/works great. Thanks for taking the time to post this how-to!

Categories